1

What is it that makes value in a variable of type _Bool have the value 1, even when we assign a value greater than 1 to it?

For example:

#include <stdio.h> int main(void) { _Bool tmp = 10; printf("%x, %lu\n", tmp, sizeof(tmp)); return 0; } 

This would print 1, 1. I am trying to understand what makes a variable of size byte act as a single bit and when assigned a value greater than 1 which has its LSB 0 still get converted to 1.

4
  • 2
    It is Implementation Defined other than 4-required macros C11 Standard - 7.18 Boolean type and values <stdbool.h> Commented Dec 3, 2019 at 7:18
  • 2
    A little unrelated nitpicking: The correct format to print a size_t (the result of the sizeof operator) is %zu. Mismatching format specifier and argument type leads to undefined behavior. Commented Dec 3, 2019 at 7:19
  • An implementation does whatever is necessary to behave as the standard prescribes. If you are interested in a particular compiler, look at the assembly it generates. Commented Dec 3, 2019 at 7:29
  • The compiler's job is to implement the rules of the language . Is your question about compiler construction or what? Commented Dec 3, 2019 at 9:27

2 Answers 2

2

What is it that makes value in a variable of type _Bool 1 , even when we assign a value greater than 1 to it. The compiler does.

For example on ARM (arm-none-eabi-gcc):

#include "stdio.h" #include "stdbool.h" int main() { _Bool tmp = 10; printf("%x , %lu", tmp, sizeof(tmp)); return 0; } 

compiles to:

.LC0: .ascii "%x , %lu\000" main: stmfd sp!, {fp, lr} add fp, sp, #4 sub sp, sp, #8 mov r3, #1 strb r3, [fp, #-5] ldrb r3, [fp, #-5] @ zero_extendqisi2 mov r2, #1 mov r1, r3 ldr r0, .L3 bl printf mov r3, #0 mov r0, r3 sub sp, fp, #4 ldmfd sp!, {fp, lr} bx lr .L3: .word .LC0 

you can see in the instruction mov r3, #1 that the compiler directly converts the initialisation value 10 to 1 as specified by the standard .

Sign up to request clarification or add additional context in comments.

Comments

1

Type _Bool type introduced in C99 has very specific semantics in the C Standard:

6.3.1.2 Boolean type
When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.

So when you attempt to store 10 to tmp, the value is converted to the destination type _Bool and according to the above paragraph, the conversion yields a value of 1.

Regarding the size of the _Bool variable tmp:

  • you should use %zu to convert values of type size_t,
  • the C Standard does not specify the size of the _Bool type:

6.5.3.4 The sizeof operator
3 When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. When applied to an operand that has array type, the result is the total number of bytes in the array. When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.

Hence sizeof(tmp) could be greater than 1, albeit this would be quite wasteful. Playing with various compilers on Godbolt's Compiler Explorer, it seems all mainstream C compilers use a single byte to store _Bool values, including MSVC.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.