Programing

"sizeof (a? true : false)"가 4 바이트의 출력을 제공하는 이유는 무엇입니까?

crosscheck 2020. 6. 29. 08:05
반응형

"sizeof (a? true : false)"가 4 바이트의 출력을 제공하는 이유는 무엇입니까?


sizeof삼항 연산자를 사용 하는 연산자 에 대한 작은 코드 조각이 있습니다 .

#include <stdio.h>
#include <stdbool.h>

int main()
{
    bool a = true;
    printf("%zu\n", sizeof(bool));  // Ok
    printf("%zu\n", sizeof(a));     // Ok
    printf("%zu\n", sizeof(a ? true : false)); // Why 4?
    return 0;
}

출력 ( GCC ) :

1
1
4 // Why 4?

하지만 여기는,

printf("%zu\n", sizeof(a ? true : false)); // Why 4?

삼항 연산자는 boolean유형을 반환 하고 sizeof bool유형은 1C의 바이트입니다.

그렇다면 sizeof(a ? true : false)4 바이트의 출력을 제공합니까?


당신이 있기 때문 #include <stdbool.h>입니다. 그 헤더 를 정의 매크로 true 와는 false할 수 10,이 같은 명세서의 외모 때문에 :

printf("%zu\n", sizeof(a ? 1 : 0)); // Why 4?

sizeof(int) 귀하의 플랫폼에서 4입니다.


여기서 삼항 연산자 반환 boolean유형은

좋아, 그 이상이 있습니다!

C 에서이 삼항 연산 의 결과 는 유형 int입니다. [아래 참고 사항 (1,2)]

따라서 결과는 sizeof(int)플랫폼 에서 식과 동일 합니다.


참고 1 : 인용 C11, §7.18,Boolean type and values <stdbool.h>

[....] 나머지 3 개의 매크로는 #if전처리 지시문 에 사용하기에 적합 합니다. 그들은

true

정수 상수 1로 확장됩니다.

false

정수 상수 0으로 확장되는 [....]

참고 2 : 조건부 연산자의 경우 §6.5.15 장 ( 강조 표시 )

첫 번째 피연산자가 평가됩니다. 평가와 두 번째 또는 세 번째 피연산자 (둘 중 평가되는 것)의 평가 사이에 시퀀스 지점이 있습니다. 두 번째 피연산자는 첫 번째 피연산자가 0과 같지 않은 경우에만 평가됩니다. 세 번째 피연산자는 첫 번째 피연산자가 0과 동일한 경우에만 평가됩니다. 결과는 두 번째 또는 세 번째 피연산자 (둘 중 평가되는 것)의 값입니다. [...]

두 번째와 세 번째 피연산자 모두 산술 유형을 갖는 경우 일반적인 산술 변환에 의해 결정되는 결과 유형은 두 피연산자에 적용되었으므로 결과 유형입니다. [....]

따라서 결과는 정수 유형이며 값 범위 때문에 상수는 정확하게 유형 int입니다.

즉, 일반적인 조언 int main()int main (void)진정으로 표준을 준수하는 것이 좋습니다.


삼항 연산자는 빨간 청어입니다.

    printf("%zu\n", sizeof(true));

4를 인쇄합니다 (또는 sizeof(int)플랫폼에있는 것).

다음은 크기가 1 인 bool동의어 char또는 유사한 유형 int이며보다 큼을 가정합니다 char.

이유 sizeof(true) != sizeof(bool)sizeof(true) == sizeof(int)있기 때문에이 단순히 true이다 없는 유형의 표현 bool. 유형의 표현식입니다 int. 이것은된다 #define로서 거라고 1에서 stdbool.h.

boolC 에는 유형의 r 값이 전혀 없습니다 . int대한 인수로 사용되는 경우에도 이러한 모든 rvalue는 즉시로 승격 됩니다 sizeof. 편집 :이 단락은 사실이 아니며, 인수로 sizeof승격되지 않습니다 int. 이것은 결론에 영향을 미치지 않습니다.


C의 부울 유형에 대해

부울 형식은 1999 년 C 언어에서 상당히 늦게 소개되었습니다. 그 전에 C에는 부울 형식이 없었지만 대신 int모든 부울 식에 사용 되었습니다. 같은 따라서 모든 논리 연산자 > == !등은을 반환 int1이나 0.

응용 프로그램에서와 같은 집에서 만든 유형을 사용하는 것은 사용자 지정이었으며 typedef enum { FALSE, TRUE } BOOL;,이 int유형 크기가 큰 유형으로 분류됩니다.

C++ had a much better, and explicit boolean type, bool, which was no larger than 1 byte. While the boolean types or expressions in C would end up as 4 bytes in the worst case. Some manner of compatibility with C++ was introduced in C with the C99 standard. C then got a boolean type _Bool and also the header stdbool.h.

stdbool.h provides some compatibility with C++. This header defines the macro bool (same spelling as C++ keyword) that expands to _Bool, a type which is a small integer type, likely 1 byte large. Similarly, the header provides two macros true and false, same spelling as C++ keywords, but with backward compatibility to older C programs. Therefore true and false expand to 1 and 0 in C and their type is int. These macros are not actually of the boolean type like the corresponding C++ keywords would be.

Similarly, for backward compatibility purposes, logical operators in C still return an int to this day, even though C nowadays got a boolean type. While in C++, logical operators return a bool. Thus an expression such as sizeof(a == b) will give the size of an int in C, but the size of a bool in C++.

Regarding the conditional operator ?:

The conditional operator ?: is a weird operator with a couple of quirks. It is a common mistake to believe that it is 100% equivalent to if() { } else {}. Not quite.

There is a sequence point between the evaluation of the 1st and the 2nd or 3rd operand. The ?: operator is guaranteed to only evaluate either the 2nd or the 3rd operand, so it can't execute any side-effects of the operand that is not evaluated. Code like true? func1() : func2() will not execute func2(). So far, so good.

However, there is a special rule stating that the 2nd and 3rd operand must get implicitly type promoted and balanced against each other with the usual arithmetic conversions. (Implicit type promotion rules in C explained here). This means that the 2nd or 3rd operand will always be at least as large as an int.

So it doesn't matter that true and false happen to be of type int in C because the expression would always give at least the size of an int no matter.

Even if you would rewrite the expression to sizeof(a ? (bool)true : (bool)false) it would still return the size of an int !

This is because of implicit type promotion through the usual arithmetic conversions.


Quick answer:

  • sizeof(a ? true : false) evaluates to 4 because true and false are defined in <stdbool.h> as 1 and 0 respectively, so the expression expands to sizeof(a ? 1 : 0) which is an integer expression with type int, that occupies 4 bytes on your platform. For the same reason, sizeof(true) would also evaluate to 4 on your system.

Note however that:

  • sizeof(a ? a : a) also evaluates to 4 because the ternary operator performs the integer promotions on its second and third operands if these are integer expressions. The same of course happens for sizeof(a ? true : false) and sizeof(a ? (bool)true : (bool)false), but casting the whole expression as bool behaves as expected: sizeof((bool)(a ? true : false)) -> 1.

  • also note that comparison operators evaluate to boolean values 1 or 0, but have int type: sizeof(a == a) -> 4.

The only operators that keep the boolean nature of a would be:

  • the comma operator: both sizeof(a, a) and sizeof(true, a) evaluate to 1 at compile time.

  • the assignment operators: both sizeof(a = a) and sizeof(a = true) have a value of 1.

  • the increment operators: sizeof(a++) -> 1

Finally, all of the above applies to C only: C++ has different semantics regarding the bool type, boolean values true and false, comparison operators and the ternary operator: all of these sizeof() expressions evaluate to 1 in C++.


Here is a snippet from which is what included in the source

#ifndef __cplusplus

#define bool    _Bool
#define true    1
#define false   0

#else /* __cplusplus */

There macros true and false are declared as 1 and 0 respectively.

however in this case the type is the type of the literal constants. Both 0 and 1 are integer constants that fit in an int, so their type is int.

and the sizeof(int) in your case is 4.


There is no boolean datatype in C, instead logical expressions evaluate to integer values 1 when true otherwise 0.

Conditional expressions like if, for, while, or c ? a : b expect an integer, if the number is non-zero it's considered true except for some special cases, here's a recursive sum function in which the ternary-operator will evaluate true until n reach 0.

int sum (int n) { return n ? n+sum(n-1) : n ;

It can also be used to NULL check a pointer, here's a recursive function that print the content of a Singly-Linked-List.

void print(sll * n){ printf("%d -> ",n->val); if(n->next)print(n->next); }

참고URL : https://stackoverflow.com/questions/47010910/why-does-sizeofa-true-false-give-an-output-of-four-bytes

반응형