Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

storage of bool in c under various compilers and optimization levels

trivial example program:

#include <stdio.h>
main()
{
    bool tim = true;
    bool rob = false;
    bool mike = true;

    printf("%d, %d, %d\n", tim, rob, mike);

}

Using the gcc compiler it appearers, based on looking at the assembly output, that each bool is stored as a bit in individual bytes:

0x4004fc <main()+8>          movb      $0x1,-0x3(%rbp)
0x400500 <main()+12>         movb      $0x0,-0x2(%rbp)
0x400504 <main()+16>         movb      $0x1,-0x1(%rbp)

if, however, one turns optimization on, is there a level of optimization that will cause gcc to store these bools as bits in a byte or would one have to put the bools in a union of some bools and a short int? Other compilers? I have tried '-Os' but I must admit I can't make heads or tails of the output disassembly.

like image 526
tallen Avatar asked Jul 26 '13 16:07

tallen


People also ask

What is compiler optimization in C?

Compiler optimization is generally implemented using a sequence of optimizing transformations, algorithms which take a program and transform it to produce a semantically equivalent output program that uses fewer resources or executes faster.

What is optimization level for GCC compiler?

GCC has a range of optimization levels, plus individual options to enable or disable particular optimizations. The overall compiler optimization level is controlled by the command line option -On, where n is the required optimization level, as follows: -O0 . (default).

When did bool add C?

C99, the version of C released in 1999/2000, introduced a boolean type. To use it, however, you need to import a header file, so I'm not sure we can technically call it “native”. Anyway, we do have a bool type.

Why is compiler optimization important?

Optimizing compilers are a mainstay of modern software: allowing a programmer to write code in a language that makes sense to them, while transforming it into a form that makes sense for the underlying hardware to run efficiently.


2 Answers

A compiler can perform any tranformations it likes, as long as the resulting behavior of the program is unaffected, or at least within the range of permitted behaviors.

This program:

#include <stdio.h>
#include <stdbool.h>
int main(void)
{
    bool tim = true;
    bool rob = false;
    bool mike = true;

    printf("%d, %d, %d\n", tim, rob, mike);

}

(which I've modified a bit to make it valid) could be optimized to the equivalent of this, since the behavior is identical:

#include <stdio.h>
int main(void)
{
    puts("1, 0, 1");
}

So the three bool objects aren't just stored in single bits, they're not stored at all.

A compiler is free to play games like that as long as they don't affect the visible behavior. For example, since the program never uses the addresses of the three bool variables, and never refers to their sizes, a compiler could choose to store them all as bits within a single byte. (There's little reason to do so; the increase in the size of the code needed to access individual bits would outweigh any savings in data size.)

But that kind of aggressive optimization probably isn't what you're asking about.

In the "abstract machine", a bool object must be a least one byte unless it's a bit field. A bool object, or any object other than a bit field, must have an unique address, and must have a size that's a whole multiple of 1 byte. If you print the value of sizeof (bool) or sizeof tim, the result will be at least 1. If you print the addresses of the three objects, they will be unique and at least one byte apart.

like image 189
Keith Thompson Avatar answered Sep 29 '22 08:09

Keith Thompson


@Keith Thompson's good answer can explain what happened with the code example in the question. But I'll assume that the compiler doesn't transform the program. According to the standard, a bool (a macro in stdbool.h the same as the keyword _Bool) must have a size of one byte.

C99 6.2.6.1 General

Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined.

This means that any type(except bit-fields, including bool) of objects must have at least one byte.

C99 6.3.1.1 Boolean, characters, and integers

The rank of_Bool shall be less than the rank of all other standard integer types.

This means bool's size is no more than a char(which is an integer type). And we also know that the size of an char is guaranteed to be one byte. So the size of bool should be at most one byte.

Conclusion: the size of bool must be one byte.

like image 26
Yu Hao Avatar answered Sep 29 '22 07:09

Yu Hao