Search code examples
c++cunsignedsigned

If an integer is signed by default, why does the signed keyword exist?


I'm curious why the signed keyword exists because I believe most integers and other variables are signed by default. Putting the signed keyword before int virtually does nothing. What is it used for, and why does it exist?


Solution

  • There are at least two places where the signed keyword is not a no-op:

    • With char: the signedness of "plain" char is implementation-defined. On implementations where it's an unsigned type, signed char is needed to get the signed variant. Even if char is a signed type, signed char, char, and unsigned char are all distinct types.

    • With bitfields: bitfield members without explicit signedness have implementation-defined signedness. For example, in

      struct foo {
          int b:1;
      };
      

      the range of values of b may be { -1, 0 } or { 0, 1 } depending on the implementation. If you want to be sure you get the signed version, you need the signed keyword. Note that while the standard is not very clear on this, on popular implementations, this applies to typedef too: if the bitfield member uses a typedef-defined type that doesn't include explicit signedness, the implementation-defined signedness (on GCC, set by -fsigned-bitfields) applies there too. This means types like int32_t should be defined using the signed keyword to avoid really bad surprise behavior when they're use in bitfields.