Can I assume the size of long int is always 4 bytes?

CLinuxTypesPosix

C Problem Overview


Is it always true that long int (which as far as I understand is a synonym for long) is 4 bytes?

Can I rely on that? If not, could it be true for a POSIX based OS?

C Solutions


Solution 1 - C

The standards say nothing regarding the exact size of any integer types aside from char. Typically, long is 32-bit on 32-bit systems and 64-bit on 64-bit systems.

The standard does however specify a minimum size. From section 5.2.4.2.1 of the C Standard:

> 1 The values given below shall be replaced by constant expressions > suitable for use in #if preprocessing directives. Moreover, > except for CHAR_BIT and MB_LEN_MAX, the following shall be > replaced by expressions that have the same type as would an > expression that is an object of the corresponding type converted > according to the integer promotions. Their implementation-defined > values shall be equal or greater in magnitude (absolute value) to > those shown, with the same sign. > > ... > > - minimum value for an object of type long int > > LONG_MIN -2147483647 // −(2^31−1) > > - maximum value for an object of type long int > > LONG_MAX +2147483647 // 2^31−1

This says that a long int must be a minimum of 32 bits, but may be larger. On a machine where CHAR_BIT is 8, this gives a minimum byte size of 4. However on machine with e.g. CHAR_BIT equal to 16, a long int could be 2 bytes long.

Here's a real-world example. For the following code:

#include <stdio.h>

int main ()
{
    printf("sizeof(long) = %zu\n", sizeof(long));
    return 0;
}

Output on Debian 7 i686:

> sizeof(long) = 4

Output on CentOS 7 x64:

> sizeof(long) = 8

So no, you can't make any assumptions on size. If you need a type of a specific size, you can use the types defined in stdint.h. It defines the following types:

  • int8_t: signed 8-bit
  • uint8_t: unsigned 8-bit
  • int16_t: signed 16-bit
  • uint16_t: unsigned 16-bit
  • int32_t: signed 32-bit
  • uint32_t: unsigned 32-bit
  • int64_t: signed 64-bit
  • uint64_t: unsigned 64-bit

The stdint.h header is described in section 7.20 of the standard, with exact width types in section 7.20.1.1. The standard states that these typedefs are optional, but they exist on most implementations.

Solution 2 - C

No, neither the C standard nor POSIX guarantee this and in fact most Unix-like 64-bit platforms have a 64 bit (8 byte) long.

Solution 3 - C

Use code sizeof(long int) and check the size. It will give you the size of long int in bytes on the system you're working currently. The answer of your question in particular is NO. It is nowhere guaranteed in C or in POSIX or anywhere.

Solution 4 - C

As pointed out by @delnan, POSIX implementations keep the size of long and int as unspecified and it often differs between 32 bit and 64 bit systems.

The length of long is mostly hardware related (often matching the size of data registers on the CPU and sometimes other software related issues such as OS design and ABI interfacing).

To ease your mind, sizeof isn't a function, but a compiler directive*, so your code isn't using operations when using sizeof - it's the same as writing a number, only it's portable.

use:

sizeof(long int)

* As Dave pointed out in the comments, sizeof will be computed at runtime when it's impossible to compute the value during compilation, such as when using variable length arrays.

Also, as pointed out in another comment, sizeof takes into consideration the padding and alignment used by the implementation, meaning that the actual bytes in use could be different then the size in memory (this could be important when bit shifting).

If you're looking for specific byte sized variables, consider using a byte array or (I would assume to be supported) the types defined by C99 in stdint.h - as suggested by @dbush.

Solution 5 - C

When we first implemented C on ICL Series 39 hardware, we took the standard at its word and mapped the data types to the natural representation on that machine architecture, which was short = 32 bits, int = 64 bits, long = 128 bits.

But we found that no serious C applications worked; they all assumed the mapping short = 16, int = 32, long = 64, and we had to change the compiler to support that.

So whatever the official standard says, for many years everyone has converged on long = 64 bits and it's not likely to change.

Solution 6 - C

The standard says nothing about the size of long int, so it is dependent on the environment which you are using.

To get the size of long int on your environment you can use the sizeof operator and get the size of long int. Something like

sizeof(long int)

> C standard only requires the following points about the sizes of types > > - int >= 16 bits, > - long >= 32 bits, > - long long (since C99) >= 64 bits > - sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) > - sizeof(char) == 1 > - CHAR_BIT >= 8 > > The remaining are implementations defined, so it's not surprised if > one encountered some systems where int has 18/24/36/60 bits, one's > complement signed form, sizeof(char) == sizeof(short) == sizeof(int) > == sizeof(long) == 4, 48-bit long or 9-bit char like Exotic architectures the standards committees care about and List of > platforms supported by the C standard > > The point about long int above is completely wrong. Most Linux/Unix > implementations define long as a 64-bit type but it's only 32 bits in > Windows because they use different data models (have a look at the > table here 64-bit computing), and this is regardless of 32 or 64-bit > OS version.

Source

Solution 7 - C

The compiler determines the size based on the type of hardware and OS.

So, assumptions should not be made regarding the size.

Solution 8 - C

From Usrmisc's Blog:

>The standard leaves it completely up to the compiler, which also means the same compiler can make it depend on options and target architecture.

So you can't.

Incidentally even long int could be the same as long.

Solution 9 - C

No, you can't assume that since the size of the “long” data type varies from compiler to compiler.
Check out this article for more details.

Solution 10 - C

Short answer: No! You cannot make fixed assumptions on the size of long int. Because, the standard (C standard or POSIX) does not document the size of long int (as repeatedly emphasized). Just to provide a counter example to your belief, most of the 64 bit systems have long of size 64! To maximize portability use sizeof appropriately.

Use sizeof(long int) to check the size, it returns the size of long in bytes. The value is system or environment dependent; meaning, the compiler determines the size based on the hardware and OS.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEliminationView Question on Stackoverflow
Solution 1 - CdbushView Answer on Stackoverflow
Solution 2 - Cuser395760View Answer on Stackoverflow
Solution 3 - CKevin PandyaView Answer on Stackoverflow
Solution 4 - CMystView Answer on Stackoverflow
Solution 5 - CMichael KayView Answer on Stackoverflow
Solution 6 - CRahul TripathiView Answer on Stackoverflow
Solution 7 - CKarthik BalaguruView Answer on Stackoverflow
Solution 8 - CsimhumilecoView Answer on Stackoverflow
Solution 9 - CRevnic Robert-NickView Answer on Stackoverflow
Solution 10 - CEhsanView Answer on Stackoverflow