I was just checking an answer and realized that CHAR_BIT
isn't defined by headers as I'd expect, not even by #include <bitset>
, on newer GCC.
Do I really have to #include <climits>
just to get the "functionality" of CHAR_BIT
?
I was just checking an answer and realized that CHAR_BIT
isn't defined by headers as I'd expect, not even by #include <bitset>
, on newer GCC.
Do I really have to #include <climits>
just to get the "functionality" of CHAR_BIT
?
Define "newer". A random Linux system gave me these results:
~> gcc --version gcc (GCC) 4.1.2 (Gentoo 4.1.2) [snip] ~> grep CHAR_BIT /usr/include/*.h /usr/include/limits.h:# define CHAR_BIT 8
Doesn't that qualify? In C, I think it should always be enough to include limits.h
to get CHAR_BIT
.
Yes, you should #include <limits.h>
to get the definition of CHAR_BIT
. It's not a bottleneck at all for your program (see comment below), and later down the line you might find yourself porting to different platforms. Not every implementation has the value of 8
<climits>
is where CHAR_BIT is required to be by the C++ standard. Even if you happened to find it in <bitset>
, its not guaranteed to be there, so you're better off going straight to the source. Its not like there's something wrong with including <climits>
.
As you may know, whether or not an implementation wants to include other headers is unspecified. It's allowed, but not mandated. (§17.4.4.1)
The only time a C++ header must include another is if it requires a definition in another. For example, <bitset>
is required to include <cstddef>
for size_t
, as this is explicitly stated in the standard. (§23.3.5, for this example)
For a counter-example, consider <limits>
. It might include <climits>
to be able to define the values for numeric_limits
and it often does, since that's easiest for an implementation. But all the standard says is things like "Equivalent to CHAR_MIN, SHRT_MIN, FLT_MIN, DBL_MIN, etc." but doesn't say it has to be implemented in terms of those, which means <climits>
doesn't have to be included.
So the only way you can be guaranteed that a CHAR_BIT
is defined is by including <climits>
or some other header where it's explicitly stated it must include it. And as far as I can tell, none have to; an implementation is free to just hard-code the value, for example, or include <limits>
and use std::numeric_limits<unsigned char>::digits
(which is equivalent), which as stated above doesn't necessary include <climits>
I keep the following function in my .profile to check compiler defined constants. On my system __CHAR_BIT__
is in there, which means no header is required if you can live with the double underscore form, which may only work with gcc.
defines ()
{
touch /tmp/defines.h;
cpp -dD "$@" /tmp/defines.h | awk '$1!="#"{COUNT+=1;print;}END{printf("count %d\n",COUNT);}' | sort;
rm /tmp/defines.h
}