Unreliable sizes for fundamental types?

I've been refreshing my knowledge of C++, and there's something that concerns me:

The size of fundamental types is not guaranteed. Apparently, all the standard guarantees is a hierarchy of sizes, and some minimum representable value range.

Specifically, a char is not guaranteed to be one byte. Also, the sizeof operator always returns 1 for the size of a char, even if the actual size is not eight bits.

Isn't this a huge problem for portability? It seems like 2+ byte characters would break all kinds of things. For example, fstream::write() takes a char * and a byte-length argument. If you ported from a 1-byte-char platform to a 2-byte platform, wouldn't that screw up all your write()s? Worse, you couldn't even detect the problem without trial and error, since sizeof would just lie to you.


I've never actually seen a platform where char wasn't 1 byte, but it sounds like a disaster waiting to happen.
You can check the number of bits in char by:

1
2
3
4
5
6
7
8
9
#include <climits>

std::clog << CHAR_BIT << '\n';

// ...

#include <limits>

std::clog << std::numeric_limits<unsigned char>::digits << '\n';


Finally, there's cstdint (the import of C99's stdint.h):
http://cplusplus.com/reference/cstdint/

I've never actually seen a platform where char wasn't 1 byte, but it sounds like a disaster waiting to happen.

A char is a byte. But a byte isn't necessarily an octet.
Last edited on
Specifically, a char is not guaranteed to be one byte.


C++ doesn't define a byte as 8-bits. IIRC, It defines it as the smallest amount of addressable memory.

A char will always be 1 "byte". But again 1 byte may not be 8-bits. It depends on the architecture.

Isn't this a huge problem for portability?


Yes an no. A 8-bit variable would be useless on a machine that is unable to have 8-bit variables. It comes down to what the hardware can do.

C++ offers a guaranteed minimum/maximum for various types. For example, char is guaranteed to be able to represent any integer between [-127,127]. So typically the exact size of a char doesn't matter.

Besides... If you need exactly 8 bits... you can use int8_t in <cstdint>.


I've never actually seen a platform where char wasn't 1 byte


Given how common it is now, and how much relies on it, popular mainstream machines will probably have 8-bit bytes for the foreseeable future.

But C and C++ don't want to be limited to "mainstream" targets... they want to be applicable to everything. So that's where there's some ambiguity here.


Really... it's not that big of a deal. I wouldn't worry about it.
@Disch
Isn't char [-128, 127]? Considering 0 to be part of the positive integers here.
signed char is guaranteed for [-127,127] because C and C++ are also defined for 1's complement arithmetic hardware (although I don't think anyone wrote a C++ compiler for UNIVAC)
MSDN documents Microsoft dialect of C++, it's quite possible that it's defined for narrower range of architectures than the standard. The tutorial is just being a tutorial.

cppreference gets in more detail http://en.cppreference.com/w/cpp/language/types

And if you want a standard reference, you'll need to make a few hops: C++ 18.3.2.4[numeric.limits.members] (footnotes 196 and 197) which refer to C++ 18.3.3[c.limits]/2 which refers to C99 5.2.4.2.1.
Topic archived. No new replies allowed.