Why is c_long a 4 byte integer in this case?

On a Windows machine I have MinGW installed

GNU Fortran (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders) 11.1.0

When I compile and run the following program, the result says that c_long is a 4 byte integer and c_int64_t is an 8 byte integer. Why do they differ?

program main
  use iso_c_binding
  integer(c_long) :: i
  integer(c_int64_t) :: j
  print*,kind(i),kind(j)
end program
1 Like

Because C on windows thinks long is a 32 bit integer.

2 Likes

I have no answer to the why, but yes with GCC under Windows the long and int have the same size, which is nevertheless C standard conforming:

  • int must be at least between -32767 and +32767
  • long must be at least between -2147483647 and +2147483647

The sizes depends on the machine, the OS, the compiler… But why on the same x86_64 machine the GCC compiler proposes different sizes on different 64 bits OS?

Concerning long long the C standard says they must be at least between -9223372036854775807 and +9223372036854775807 (-2^{63}-1 and +2^{63}-1). Therefore at least 64 bits.

2 Likes

Thanks! I’m using a mix of Fortran and C. Will c_long always map to long in C the right way?

Yes it should, the Fortran 2018 standard says Table 18.2 that c_long is interoperable with long int, and c_int64_t with int64_t.
And there is also c_long_long for long long int (as far as I remember they are 64 bits both under Windows and Linux).

But it’s interoperable under all systems only if you respect the minimal range printed in the C standard…

2 Likes

64-bit computing - Wikipedia

Each platform has decided on the model to follow, and a compiler that chooses otherwise will find itself not popular.

4 Likes