28

C++ standard says only that int has to be at least 16 bits wide. And at least according to cppreference, it's almost always either 16 or 32 bits wide:

data model       int width in bits
----------------------------------
C++ standard     at least 16
LP32             16
ILP32            32
LLP64            32
LP64             32

...

Other models are very rare. For example, ILP64 (8/8/8: int, long, and pointer are 64-bit) only appeared in some early 64-bit Unix systems (e.g. Unicos on Cray).


Is there an example of a currently used system with a C++ compiler where int is over 32 bits wide? By currently used I mean e.g. some old system maybe still actively used by a specific industry because there's a valid reason to use it for that specific task and which cannot reasonably be replaced with something else. Preferably this would be something that's actively being developed/worked on, and not just a system running legacy code, which hasn't been touched in 20 years. A modern system with for example 64 bit int, which is used for scientific computing would also be an excellent answer.

I am not looking for a system that was used 2 years in the 90s and then dumped completely. I'm also not looking for something which is only used as a hobby to play around, or some old system, which two companies in the world use just because they are too cheap to upgrade.

ruohola
  • 21,987
  • 6
  • 62
  • 97
  • 1
    For what is worth, skimming through GCC sources, `int` types for all architectures seem to be either 16 or 32 bits... except for some small Atmel AVR chips, where it is 8 bits! – rodrigo Jul 25 '19 at 21:32
  • And if you would define `obsolete` as _not running Debian_ the answer would be ["no"](https://wiki.debian.org/ArchitectureSpecificsMemo#Summary). – rodrigo Jul 25 '19 at 21:34
  • @ruohola I think this can be interpreted as an opinionated question. Whether or not a particular system is considered obsolete depends on who you're asking. What about Univac with its 9 bit `char` type and its 36 bit `int` type? Is that obsolete? – AlwaysLearning Jul 25 '19 at 21:37
  • @AlwaysLearning I've tried to explain what I consider to be non obsolete in the end of my question. I've never heard of Univac before this, so had to google it. Is there any industry which uses such computer anymore? Is it in any way relevant today? – ruohola Jul 25 '19 at 21:39
  • IBM iSeries now uses 64-bit PowerPC chips and is backward compatible with 48-bit proprietary hardware. Not sure what the int size is now, but that's what I would look at. IBM has their own C compiler. – stark Jul 25 '19 at 21:47
  • @AlwaysLearning If you have an example of non-esoteric modern day usage of a 36 bit `int` UNIVAC that'd be a great answer! – ruohola Jul 25 '19 at 21:50
  • google "ILP64" for latest results! – M.M Jul 25 '19 at 22:22
  • 1
    Hmm... "non-obsolete" does invoke subjective meanings. Perhaps reword that to something more objective like "currently used" or "non-abandoned"? To demonstrate that a system is not abandoned, you would just need to name one entity still using it. This wouldn't change the question's intent, but could change how the question is perceived. – JaMiT Jul 25 '19 at 22:42
  • Reworded the question to be as clear as possible and as little subjective as possible. – ruohola Jul 25 '19 at 23:18
  • 1
    I'm sure, i've used gcc / clang / msvc in last 5 years somewhere, which produced int as 64 bit (which got me by suprise). Real question is - why are you asking? Because if the need for knowing the answer (beside curiosity) suggests, that you're doing something wrong already. Use `std::int32_t` if you need 32 bit int. int is a "common" integer, big enough to deal with common math result and is bound to be 64 bit at some point in future, so relying on it being 32 bit forever is a mistake. – Radosław Cybulski Jul 26 '19 at 06:34
  • @RadosławCybulski This is just for research and general curiosity about the subject. – ruohola Jul 26 '19 at 06:39
  • 1
    @rodrigo: AVR uses 16 bit int as long as you do not run gcc with `-mint8` – Klaus Jul 26 '19 at 08:41
  • 2
    It anyone finds something that answers this question they should also add an answer to [Exotic architectures the standards committees care about](https://stackoverflow.com/q/6971886/1708801) – Shafik Yaghmour Aug 05 '19 at 04:53
  • 1
    IIRC when porting some network testing software to Unicos on a Cray J90, I found `int` to be a surprise. It was 8 bytes... unusual enough, but INT_MAX was a smaller value than would fit within its storage space! The difference between int and long was speed. int values were constrained to fit within the significant bits of floating point hardware. Very unique hardware design. Dealing with full 64-bit integer math (C `long`) was a slow software operation. https://yarchive.net/comp/cray_integers.html hints at this. – gps Oct 14 '21 at 09:13

2 Answers2

15

Please note that this answer is intended as a frame challenge; that even 64 operating systems wouldn't normally want >32 bits due to several points. Which means it is unlikely a team would go through the effort of creating an operating system without already having taken into consideration these points and even less likely that it'd be non-obsolete by this point in time. I hope a more direct answer is found, but I think that this justifies at least the major operating system's decisions.

To get started, you are correct that the C++ draft permits for plain ints that are permitted to be wider than 32 bits. To quote:

 Note: Plain ints are intended to have the natural size suggested by the architecture of the execution environment; the other signed integer types are provided to meet special needs. — end note

Emphasis mine

This would ostensibly seem to say that on my 64 bit architecture (and everyone else's) a plain int should have a 64 bit size; that's a size suggested by the architecture, right? However I must assert that the natural size for even 64 bit architecture is 32 bits. The quote in the specs is mainly there for cases where 16 bit plain ints is desired.

Convention is a powerful factor, going from a 32 bit architecture with a 32 bit plain int and adapting that source for a 64 bit architecture is simply easier if you keep it 32 bits, both for the designers and their users in two different ways:

The first is that less differences across systems there are the easier is for everyone. Discrepancies between systems been only headaches for most programmer: they only serve to make it harder to run code across systems. It'll even add on to the relatively rare cases where you're not able to do it across computers with the same distribution just 32 bit and 64 bit. However, as John Kugelman pointed out, architectures have gone from a 16 bit to 32 bit plain int, going through the hassle to do so could be done again today, which ties into his next point:

The more significant component is the gap it would cause in integer sizes or a new type to be required. Because sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) is in the actual specification, a gap is forced if int is moved to 64 bits, a gap is simply inevitable. It starts with shifting long. If a plain int is adjusted to 64 bits, the constraint that sizeof(int) <= sizeof(long) would force long to be at least 64 bits and from there there's an intrinsic gap in sizes. Since long or a plain int usually are used as a 32 bit integer and neither of them could now, we only have one more data type that could, short. Because short has a minimum of 16 bits if you simply discard that size it could become 32 bits and fill that gap. However short is intended to be optimized for space so it should be kept like that and there are use cases for small, 16 bit, integers as well. No matter how you arrange the sizes there is a loss of a width and therefore use case for an int entirely unavailable.

This now would imply a requirement for the specifications to change, but even if a designer goes rogue, it's highly likely it'd be damaged or grow obsolete from the change. Designers for long lasting systems have to work with an entire base of entwined code, both their own in the system, dependencies, and user's code they'll want to run and a huge amount of work to do so without considering the repercussions is simply unwise.

As a side note, if your application is incompatible with a >32 bit integer, you can use static_assert(sizeof(int) * CHAR_BIT <= 32, "Int wider than 32 bits!");. However, who knows maybe the specifications will change and 64 bits plain ints will be implemented, so if you want to be future proof, don't do the static assert.

ruohola
  • 21,987
  • 6
  • 62
  • 97
David Archibald
  • 1,431
  • 14
  • 27
  • 10
    I'm not sure I buy the argument that going from 32- to 64-bit ints would be too much of a headache to be worthwhile. Going from 16- to 32-bit ints was a huge pain in the neck, but it was done. No, my recollection of why ints never grew to 64 bits is that it would leave a gap in the C type system. You'd have 16-bit shorts and 64-bit ints with no integral type in the middle. How would you make a 32-bit integer? It was avoidance of that scenario that led to our present-day situation where ints are no longer the *natural word size* on 64-bit systems. – John Kugelman Jul 25 '19 at 22:16
  • @JohnKugelman Isn't `long` an integral type([reference](https://en.cppreference.com/w/cpp/language/type)) that's usually 32 bits or am I missing something? Albeit it seems that `long` *is* 64 bits on LP64, but that's a shifting around, not an intrinsic gap. – David Archibald Jul 25 '19 at 22:51
  • 1
    long has to be at least as large as int. If int were 64 bits then long would have to be >= 64 bits. – John Kugelman Jul 25 '19 at 23:18
  • Ah I see, I had forgotten that plain ints can't just jump ahead of a long by specification not by convention. Since I thought your comment was very valuable, I've integrated into my answer. I hope you don't mind. – David Archibald Jul 25 '19 at 23:33
  • @DavidArchibald This answer would be a great answer for: https://stackoverflow.com/questions/17489857/why-is-int-typically-32-bit-on-64-bit-compilers? – ruohola Aug 02 '19 at 09:42
  • @ruohola that's a great idea! I've "crossposted" it [there](https://stackoverflow.com/a/57329946/5461005), but I'm going to leave it here too, at least for now because there's not been an answer that more adequately fulfills your question's conditions yet. – David Archibald Aug 02 '19 at 15:58
  • @DavidArchibald Yeah ofc keep your answer, if I can't get a more suitable answer by 3 days, I will just award the full bounty to you :) – ruohola Aug 02 '19 at 16:09
  • Enjoy the bounty :) – ruohola Aug 05 '19 at 16:26
  • Thank you, @ruohola, and sorry you couldn't get a more suitable answer in time! – David Archibald Aug 05 '19 at 16:58
  • Related: https://unix.org/version2/whatsnew/lp64_wp.html explains the merits of an LP64 model (like most Unix systems) or LLP64 (like Windows x64) vs. an ILP64 model with int = int64_t (most programs will waste lots of cache footprint on `int` arrays, and binary file formats will be incompatible if they depend on int; apparently lots of old code wasn't careful with serialization and did have file formats dependent on C types) – Peter Cordes May 01 '21 at 02:30
2

I still think this is an opinionated question. Though Univac is by no means common there are still working examples on display such as the Univac 9400 in the technikum29 living computer museum near Frankfurt in Germany. People are still maintaining that in working order.

"The New C Standard (Excerpted material)" dated 2002-2008 says:

Common Implementations

The values that are most often greater than the ones shown next are those that apply to the type int. On hosted implementations they are often the same as the corresponding values for the type long. On a freestanding implementation the processors’ efficiency issues usually dictate the use of smaller numeric ranges, so the minimum values shown here are usually used. The values used for the corresponding character, short, long, and long long types are usually the same as the ones given in the standard.

The Unisys A Series[5] is unusual in not only using sign magnitude, but having a single size (six bytes) for all non-character integer types (the type long long is not yet supported by this vendor’s implementation).

#define SHRT_MIN (-549755813887)
#define SHRT_MAX 549755813887
#define USHRT_MAX 549755813887U
#define INT_MIN (-549755813887)
#define INT_MAX 549755813887
#define UINT_MAX 549755813887U
#define LONG_MIN (-549755813887L)
#define LONG_MAX 549755813887L
#define ULONG_MAX 549755813887UL

The character type use two’s complement notation and occupies a single byte.

The C compiler for the Unisys e-@ction Application Development Solutions (formerly known as the Universal Compiling System, UCS)[6] has 9-bit character types — 18-bit short, 36-bit int and long, and 72-bit long long.

REF: http://c0x.coding-guidelines.com/5.2.4.2.1.pdf

AlwaysLearning
  • 7,915
  • 5
  • 27
  • 35
  • 1
    Hmm, I don't think anyone would classify *a working computer in a museum* to be in any way relevant in the industry. Also as far as I can see the reference you linked is only talking about a C compiler, not C++ compiler. – – ruohola Jul 25 '19 at 22:12
  • @ruohola This is exactly why your question is opinionated. I satisfied your condition but you argue the point. "*obsolete* adjective. no longer produced or used; out of date." The Univac is still used, therefore it is not obsolete. – AlwaysLearning Jul 26 '19 at 00:25
  • 2
    I've refined my question a bit, I think you will agree also that there's no opionation in it now. – ruohola Jul 26 '19 at 05:51