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
}