1

I'm aware that there are a few accepted implementations of how signed integers are stored, specifically negative values. There's two's complement, one's complement, and sign/magnitude. For Visual C++, which one is implemented? I am a bit uncertain. I've always thought that it was sign/magnitude implementation.

Is this architecture dependent or maybe compiler dependent?

7
  • 2
    This depends on the processor architecture, not the language. With that said, I'm not aware of any modern architectures that do not use 2's complement.
    – JMekker
    May 11, 2022 at 16:33
  • 1
    It's simpler to implement and has less edge cases to deal with (no "-0", etc). The wiki article has a few paragraphs on the benefits: en.wikipedia.org/wiki/Two%27s_complement
    – JMekker
    May 11, 2022 at 16:48
  • 6
    @JMekker: "This depends on the processor architecture, not the language" – As of ISO C++20, that is no longer true. ISO C++20 removed support for any representation other than two's complement. Technically speaking, it is still possible to store them differently and transparently convert back and forth, as long as the program cannot tell that is happening. But from the point-of-view of the ISO C++20 Abstract Machine, two's complement representation is the only representation. May 11, 2022 at 16:50
  • 1
    I guess it depends on the level of abstraction you look at: are you looking at what a C++ program can observe or are you looking at the actual CPU register with an electron microscope. May 11, 2022 at 16:52
  • 1
    @J113: In that case, regardless of how the CPU stores it, ISO C++20 now specifies that any conforming implementation must behave AS-IF signed integers were stored in two's complement representation. Note that there was not much resistance from either the representatives of the compiler vendors (Clang, GCC, MSVC, IBM xlc, Metrowerks, Pathscale, Oracle, HP, etc.) or the CPU vendors because none of the current mainstream compilers even support one's complement or sign/magnitude anymore, and all current mainstream CPUs use two's complement. May 11, 2022 at 17:00

1 Answer 1

7

In C++, how is signed integer stored?

The C++ specification does not prescribe any particular storage representation for signed integers on the actual hardware level. An implementation is free to store signed integers however it wants.

C++ only prescribes the behavior of signed integers, not the representation. (That's not just true of signed integers, and not just true of C++. Almost every programming language does not specify particular representations, for any type.)

To be more precise: the ISO C++ specification describes the behavior of an ISO C++ Abstract Machine, but there is no requirement that the actual hardware must behave this way.

There's two's complement, one's complement, and sign/magnitude.

Until recently, C++ was very careful to define the behavior in such a way that all three of the above-mentioned representations (two's complement, one's complement, and sign/magnitude) can be used without incurring a performance penalty.

However, that has recently changed. ISO C++20 was the first version of C++ that removed support for one's complement and sign/magnitude. Note that this still does not mean that ISO C++20 requires signed integers to be stored in two's complement representation. It only means that conforming implementations must behave AS-IF signed integers were stored in two's complement representation.

Also, note that the C++ Committee explicitly chose to leave some behaviors as Undefined Behavior even though they could now theoretically be implementation-defined or even well-defined.

See also this Stack Overflow question: Ramifications of C++20 requiring two's complement

The ISO C working group has watched this with interest and is also considering removing support for anything other than two's complement representation from ISO C.

For Visual C++, which one is implemented?

Microsoft Visual C++ only supports (or at least supported at one point or another) a limited number of platforms (Windows NT, Windows CE, Windows, DOS, maybe some others I can't remember off the top of my head) and a limited number of architectures (AMD64, x86, ARM64, ARM, Alpha, MIPS, Sparc, PowerPC, PPC64, i860). For all possible combinations of those which are supported by Microsoft Visual C++, it uses two's complement representation, which is also the representation that is natively used by those architectures.

Even before ISO C++20, Microsoft Visual C++ has only ever supported two's complement representation.

Is this architecture dependent or maybe compiler dependent?

It is both. Although it is unlikely that a compiler would choose a different representation than the native representation of the architecture, that is entirely possible and allowed by the standard. It will just be somewhat slower because of all the conversions back and forth the compiler has to generate.

It looks like all the architectures which are supported by modern C++ compilers are two's complement, and none of the compilers for architectures which aren't two's complement support modern versions of C++. Therefore, there was no harm in removing support for anything except two's complement; current mainstream compilers didn't need to do anything, because they were already using two's complement.

The only known compiler which doesn't use two's complement is the Unisys Clearpath MCP C compiler, which uses sign/magnitude. However, that compiler only supports ISO C90 and has not been updated since 2017. So, if a future standard removes support for sign/magnitude, it is highly unlikely that Unisys will all of a sudden want to release a new version of their compiler which implements ISO C 2027 or whatever the next version will be.

Which means that the days of non two's complement representations are over in C++ and numbered in C.

But again, this only concerns the behavior, not the actual storage. As long as a program cannot actually notice that signed integers are not stored in two's complement representation, you can store them as pieces of cheese if you want.

4
  • I consider the potential relevance of platforms more amenable to non-2s-complement integers more important than the number or modernity of implementations for such when pondering mandatory 2s-complement. Though they certainly are strongly correlated. And I think whatever is left in this case is dinosaurs people really want to abandon (if only program XYZ could be migrated somehow). May 11, 2022 at 17:16
  • @Deduplicator: the point that the committee is making is that even if the platform is hugely popular and hugely relevant, this standards change only hurts the compiler vendors IFF they actually upgrade to ISO C++20 compliance. A compiler vendor who intends to stick to C++89 for all eternity will not be affected by changes to a future standard. All compilers that support even just C++11 already only supported two's complement anyway. Unisys implements C90 at the moment, and they have no intention to upgrade to even C99 let alone a hypothetical future two's complement only standard. May 11, 2022 at 18:40
  • If I understood correctly, the C committee intends to give compiler vendors 5 years to argue against the change. The people who use Unisys do not want the compiler to change in any way, because for them, the value proposition is to compile millions of lines of code whose authors are long dead. Nobody is going to write a greenfield project in C++20 or C23 on Unisys. May 11, 2022 at 18:42
  • Also, there's endianness, which goes to representation that C++ also doesn't specify.
    – Erik Eidt
    May 11, 2022 at 22:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.