Since I’m working on a Lazarus SDL3 Pascal binding, I wanted to use cbool
there and noticed that it’s 4 bytes in size. This obviously stumped me, because bool
in SDL3 is 1 byte in size. So I asked in the German Lazarus forum why cbool
is 4 bytes in size and received the following answer. Is this statement true?
German:
Ganz einfach: der meiste C Code nutzt typedef int bool oder analoges um einen Boolean-Wert dazustellen. Dass mehr auf einen standardisierten Booleantyp gegangen wird, ist erst seit vergleichsweise Kurzem der Fall. Demnach deckt cbool auch den häufigeren Fall für C-Code ab und wird aus Gründen der Rückwärtskompatibilität auch so bleiben.
Wenn du Kompatibilität zu C’s _Bool (bis C23) bzw. bool (seit C23) möchtest, dann nimm Boolean bzw. Boolean8 her, da diese die gleiche Semantik haben.
English:
Quite simply: most C code uses typedef int bool or something similar to represent a Boolean value. The move toward a more standardized Boolean type has only been the case relatively recently. Therefore, cbool also covers the more common use cases for C code and will remain so for reasons of backward compatibility.
If you want compatibility with C’s _Bool (up to C23) or bool (since C23), then use Boolean or Boolean8, as they have the same semantics.
from C11 6.2.5p2:
An object declared as type _Bool is large enough to store the values 0 and 1.
So it could be 8 bits, 9 bits or 32 bits. It is implementation defined, C code uses sizeof
and CHAR_BIT
to know this for sure.
from C11 6.2.5p5:
A ‘‘plain’’ int object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the range INT_MIN to INT_MAX as defined in the header <limits.h>).
and on C11 5.2.4.2.1 states that INT_MIN
is -32767 (not -32768) and that INT_MAX
is +32767. so even though 4 bytes is common, it could be as small as 2 bytes or be 8 bytes or more, again, use sizeof
and CHAR_BIT
to know this for sure.
dunno what you want to do with this information. good luck.
The main issue is this line, which returns a Boolean array.
extern SDL_DECLSPEC const bool * SDLCALL SDL_GetKeyboardState(int *numkeys);
In SDL3, the bool
is 1 byte in size.
If the bool
has a different size in the main function, it no longer works.
When SDL_bool
still existed, the whole thing was unambiguous.
1 Like
dunno what to make out of this. I don’t see the problem
can you use this Boolean8
?
For my project I maintain my own SDL3 headers for Free Pascal where I use the basic Boolean type (always 8-bit) everywhere and I have no problem with it. So I don’t know if it’s anything to worry about.
bool
should be 8-bit everywhere, always and for every platform, because AFAIK there is no reason for it to take up more bytes. Internally, the SDL may use wider boolean types, e.g. if the Win32 API functions require it, but externally (i.e. to the SDL user), all functions should use 8-bit bool, to keep usage simple and to avoid ambiguity.
The C standard doesn’t even require that “bytes” (chars) are 8 bits. Some hardware might have say 12 or 18 bits as the “smallest addressable unit”. This is very unusual, not sure if it even exists today, but that is what the standard want to allow and a big reason why sizes are left “implementation defined”. Question is, could SDL3 (or any of your favourite OS/software for that matter) run on such hardware? I think not, because you wouldn’t be able to have things like Uint8
/uint8_t
which would break a lot of things.
sizeof(bool)
is still allowed to be bigger than 1 but I agree that there is no reason for it to be (except maybe to keep compatibility with old C code that used int
for Booleans). It looks like SDL3 relies on sizeof(bool)
to be equal to 1, because it asserts this fact in SDL_stdinc.h, so if you use SDL3 it seems safe to assume that bool
is indeed 8 bits.
1 Like
I don’t know if FPC even supports compiling for machines that use non-8-bit wide bytes (I doubt it), but even if it does, the underlying Boolean type will still be the size of the smallest allocation unit. So there’s nothing to worry about here, and what’s more, we couldn’t do anything about it anyway.
Indeed, I think so as well. This assertion ensures that the size of bool is 1
allocation unit (by default one byte), so the Pascal type Boolean
is suitable and it can be safely used.
1 Like
So, in standard C, you can rely on a bool
being one byte. Thus, the ctypes unit is useless in Lazarus. Then you want to use the unit with the cbool
, thinking it will be C compatible, even though it has 4 bytes!
This is why C sucks — Pascal on its own doesn’t have such a mess with data types. 
I think cbool
is declared as 32-bit longbool
because of the target platform. If the target is Win32-x64, then cbool
is compatible in size with the BOOL
type used by the system API, which resolves to an int
:
If the target is Unix, then the cbool
type declaration from the unixtype
module applies, which interestingly also resolves to longbool
:
I think it would be a good idea for you to ask the FPC developers directly why these data types are declared this way and what they are supposed to be compatible with.
That’s exactly what I did, and that’s where I got the text in the first post from.
What I’m wondering is why the SDL3 developers abandoned SDL_bool
; if you used SDL_bool
, you couldn’t go wrong.
In Pascal, it was TSDL_bool
or PSDL_bool
.
Other platforms, like OpenGL, have their own Boolean.
You said that you asked on the German Free Pascal forum, and I mean specifically the Free Pascal Forum and especially the user @PascalDragon, who is the main developer of the FPC compiler.
You said that you asked on the German Free Pascal forum, and I mean specifically the Free Pascal Forum and especially the user @PascalDragon, who is the main developer of the FPC compiler.
Oops, I forgot the link.
Gemeine Falle mit C Boolean
1 Like
I’m not exactly sure why they chose standard C bool over SDL_bool, with the requirement of it being 8-bit, but I can say that because SDL3 requires some (not all) C99 features not in C89/C90, the option to use standard C bool became available. As SDL2 and earlier only required C89/C90, there wasn’t the option to use standard C bool, so using some other type/typedef was required.
Not all C99 features are required by SDL3, to support not-quite-C99 compilers, such as the nonstandard pre-C11 C dialect supported by MSVC; Microsoft never provided full C99 support in their C compiler for various reasons, but did start doing a better job of standard C support starting with C11.
What are the benefits of using a data type wider than a single byte for storing false/true?
What are the benefits of using a data type wider than a single byte for storing false/true?
I don’t see any advantage either, but I have seen C libs that use a 32-bit Boolean.
Possibly that on some architectures there’s a speed penalty for non-32-bit-aligned accesses. Basically the same reason we don’t use a single bit, because it can be expensive to extract.
2 Likes
another advantage of a 32-bit boolean is that you can have many meaningful truthy values
typedef int MyBool;
MyBool success = 0; // failure, no collisions
success = 1; // compute shader detected AABB collisions
success |= 2; // compute shader detected intersection between two segments
success |= 4; // compute shader detected a segment entirely inside a polygon
success |= 8; // compute shader detected a segment crossing a rotated rectangle
success |= 16; // [...]
take this as a mix of sarcasm and actual sad experiences
another advantage of a 32-bit boolean is that you can have many meaningful truthy values
typedef int MyBool;
MyBool success = 0; // failure, no collisions
success = 1; // compute shader detected AABB collisions
success |= 2; // compute shader detected intersection between two segments
success |= 4; // compute shader detected a segment entirely inside a polygon
success |= 8; // compute shader detected a segment crossing a rotated rectangle
success |= 16; // [...]
take this as a mix of sarcasm and actual sad experiences
In such a case, isn’t it better to use an int?
yep. or an enum
that’s part of the sarcasm 