21

Many sources, including Microsoft, reference both the int and long type as being 4 bytes and having a range of (signed) -2,147,483,648 to 2,147,483,647. What is the point of having a long primitive type if it doesn't actually provide a larger range of values?

mikalai
  • 1,746
  • 13
  • 23
hodgesmr
  • 2,765
  • 7
  • 30
  • 41
  • Even if it is up to the platform to specify the size, what is the value in defining them congruently? – hodgesmr Nov 15 '12 at 13:40
  • `sizeof(int)` and `sizeof(long)` are platform dependent. For platform independent code you can use, the types like `intN` where N is number of bits. – iammilind Nov 15 '12 at 13:41
  • 4
    @hodgesmr: `int` is 32 bits on your implementation. `long long` is 64 bits. So what size in between would *you* pick for `long`? Historically, on Windows it has stayed at 32 bits since the days when `int` was 16 bits on Windows. I vaguely suspect that Windows 95 would have been the first with a 32 bit `int`, but I wasn't programming C then so I don't know. – Steve Jessop Nov 15 '12 at 13:44
  • 1
    It would be entirely OK for an implementation to make *all* integral types 256 bits long, so they would all have `sizeof == 1`. That would vindicate `std::vector`, too! – Kerrek SB Nov 15 '12 at 13:47
  • @KerreSB: well, you get some problems with stuff like `getc`, `tolower` if not every value of `unsigned char` can be represented in `int`. It becomes impossible to distinguish between `EOF`, and `(int)UCHAR_MAX`, or to call the character functions for those values. – Steve Jessop Nov 15 '12 at 14:48
  • @SteveJessop I'm more thinking what a bitch it would be to do single octet work in general. Outside of that I like the novelty of the idea. – WhozCraig Nov 15 '12 at 14:49
  • @WhozCraig: there are DSPs on which `char` is bigger than 8 bits. Basically you *don't* work with octets, there's not much reason to for the kinds of program expected to run on that hardware. Even for DSPs though, 256 is probably excessive. – Steve Jessop Nov 15 '12 at 14:50
  • @SteveJessop that makes total sense. I'm also imagining how awesome it would be to have *everything* auto-aligned by default. – WhozCraig Nov 15 '12 at 14:52

8 Answers8

35

The only things guaranteed about integer types are:

  1. sizeof(char) == 1
  2. sizeof(char) <= sizeof(short)
  3. sizeof(short) <= sizeof(int)
  4. sizeof(int) <= sizeof(long)
  5. sizeof(long) <= sizeof(long long)
  6. sizeof(char) * CHAR_BIT >= 8
  7. sizeof(short) * CHAR_BIT >= 16
  8. sizeof(int) * CHAR_BIT >= 16
  9. sizeof(long) * CHAR_BIT >= 32
  10. sizeof(long long) * CHAR_BIT >= 64

The other things are implementation defined. Thanks to (4), both long and int can have the same size, but it must be at least 32 bits (thanks to (9)).

Griwes
  • 8,805
  • 2
  • 43
  • 70
  • 2
    Slightly off-topic, but for C++11, you can add `sizeof(long) <= sizeof(long long)` and `sizeof(long long)*CHAR_BIT >= 64`. – Mike Seymour Nov 15 '12 at 13:59
  • 1
    The size ranges of the various types are not the *only* thing guaranteed about these types. The Standard also guarantees the minimum and maximum values that certain types can represent. See [here](http://stackoverflow.com/questions/4329777/is-long-guaranteed-to-be-at-least-32-bits) for more info. – John Dibling Nov 15 '12 at 14:10
  • @JohnDibling, maximum and minimum values are implied by minimum size for each type ((6) - (10)). – Griwes Nov 15 '12 at 14:13
  • @Griwes: For some types the min/max values are not implied. They are directly expressed in the Standard. – John Dibling Nov 15 '12 at 14:14
  • 1
    @JohnDibling, or the other way around: size is implied by minimum and maximum values. Which is the case here; you need at least 32 bits to represent `INT_MAX` and `INT_MIN` and so on. It's still in the answer. – Griwes Nov 15 '12 at 14:15
  • @Griwes: I'm not saying your answer is wrong. I'm simply adding some color for future readers. If I had thought your answer was wrong, I would have d/v'ed, which I did not. – John Dibling Nov 15 '12 at 14:16
  • @JohnDibling, I'm not saying you are saying so; I'm just saying that those guarantees boil down to the same thing. – Griwes Nov 15 '12 at 14:18
  • @bames53, non-binary hardware wouldn't use "bits" as basic unit, so nothing in standard mentioned here that says about types (thanks to definition of `CHAR_BIT` - note the *bit* part of that constant) would apply. Also, do you know any non-binary hardware that is anywhere else than in "proof of concept" phase? – Griwes Nov 15 '12 at 16:32
  • The requirements mentioned by the standard do apply; they're not stated in terms of bits. sizeof(char)==1, sizeof(int)<=sizeof(long), INT_MAX>=32767, LONG_MAX>=2147483647, etc. No, I'm not aware of any such implementations. – bames53 Nov 15 '12 at 18:42
  • @bames53, hmm, `char` has `CHAR_BIT` bits. How can it have `CHAR_BIT` bits, if there are no bits? – Griwes Nov 15 '12 at 18:44
  • There are probably a number of issues a non-binary implementation would have to deal with. Although CHAR_BIT is only the "number of bits for smallest object that is not a bit-field". So maybe a char doesn't need to have CHAR_BIT bits... – bames53 Nov 15 '12 at 18:53
  • @bames53, `char` definitely looks like `smallest object that is not a bit-field`, thanks to (1) - (5). – Griwes Nov 15 '12 at 18:55
  • The smallest only of the listed types, but maybe CHAR_BIT could refer to some other type. – bames53 Nov 15 '12 at 19:10
20

C++ standard only specifies that long is at least as big as int, so there's nothing criminal in the scenario when it is exactly as big: it's totally implementation-defined. On different platforms, sizes may matter, for example I'm having int of size 4 and long of size 8 at the moment on my Linux machine.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
10

As other have pointed out, the assumption underlying the question is only partially true, i.e. doesn't hold for some platforms. If you really want to understand how we came to the current situation, the Long Road to 64 Bits by J. Mashey will give you a good view on the various forces in presence and how they interacted.

Quick summary, C started with char (8 bits) and int (16 bits). Then one added short (16 bits) and long (32 bits), while int could be 16 or 32 bits depending on what was natural on the platform and the pressure of backward compatibility. When 64 bits came, long long was added as a 64 bits type and there was some adjustments in the smaller types on 64 bits platforms. Things stabilized with a 32 bits int, but long kept various definitions, some 64 bits platforms having a 64 bits long, while other (perhaps only Windows?) kept long to 32 bits, probably due to different pressure of backward compatibility (Unix had a long history of assuming long as the same size as a pointer, Windows had more remnant in its API of the time when int was 16 bits and thus long was the only 32 bits type). BTW typedefs (intXX_t, intptr_t) were added to help to make the intention clearer, at the risk for the intXX_t family to force constant size were none is really needed.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
  • Thanks. I hate the answers that just spews out standards. Everyone knows that. The more important thing is why the standards are in the way that they are. Even more importantly, why the major implementations does the thing in this weird way, Your answer helps to understand that. – Shital Shah May 01 '17 at 22:46
3

No, it's only 4 bytes on certain platforms. The C++ standard leaves the size as being implementation-defined.

On other platforms it may be a different size.

slaphappy
  • 6,894
  • 3
  • 34
  • 59
Pubby
  • 51,882
  • 13
  • 139
  • 180
  • @juanchopanza: there are minimum ranges specified. Knowing `CHAR_BIT` on the implementation you can deduce from that a minimum size. – Steve Jessop Nov 15 '12 at 13:42
  • @SteveJessop right. I was pretending OP's question was phrased purely in terms of bytes, for which the minimum sizes are fixed, but they have thrown some min and max numbers in, which confuse the issue a bit. – juanchopanza Nov 15 '12 at 14:00
3

It doesn't necesarily have to be larger. It's just the way the GCC, for example, usually has long to be defined as 8 bytes when I've used it on my machine. The standard's wording usually says that these types 'Need to be at least X size' (for an example, check out the finally-standardized long long in C++11.

Essentially, anyone's free to do what they want as long as it meets the requirements. According to the standard, someone could make long long 256 bits, and it'd be perfectly legal.

3

The C++ Language Specification simply states that the size of a long must be at least the size of an int.

It used to be standard to have int = 2 bytes and long = 4 bytes. For some reason int grew up and long stayed the same (on Windows compilers at least). I can only speculate that long was kept the same for reasons of backwards compatibility...

Roy Dictus
  • 32,551
  • 8
  • 60
  • 76
  • This question is not about C at all – thecoshman Nov 15 '12 at 13:48
  • Why speculate when you have a ISO standard defining clearly the whereabouts of the types lengths ? – slaphappy Nov 15 '12 at 13:50
  • 2
    The standard says that long must be at least the size of int, it does not say that it must be 4 bytes, or *why* in the Windows C/C++ compilers, it is 4 bytes. Please read the answer properly before you downvote. – Roy Dictus Nov 15 '12 at 13:52
1

No one has answered your actual question, except maybe AProgrammer.

The C/C++ standard is defined as Griwes described. This allows the C and the C++ language to be implemented where the compiler vendor can define the sizes most convenient to the computer architecture. For a while, (for Windows 3.1 and before, that is, before Windows 95), C code for windows had a 16 bit int whereas many UNIX platforms, such as Solaris, HPUX, and AIX had a 32 bit int.

However, modern microcomputers (since the 386), have full 32 bit registers, and addressing memory aligned to 32 bits is much faster then accessing 16 bit increments. Thus code is much more efficient with a 32 bit int, especially for int arrays, than it might be with a 16 bit int.

To simulate a 16 bit int in a 32 bit register, you also have to overflow at the 16th bit, instead of the 32nd. So it's just easier with a 32 bit int, even if you only have 32 bits available for long.

Marlin Pierce
  • 9,931
  • 4
  • 30
  • 52
0

I think it's implementation dependent. They can vary, but it is up to the vendor to supply them. However, some vendors simply make it so that they are syntactically "supported" (ie: you can put them in your code and they will compile, but don't differ). Every so often, you'll encounter a language feature like this.

RonaldBarzell
  • 3,822
  • 1
  • 16
  • 23