Unexpected output in converting from long in C to long in C++ in VS?

Viewed 80

I'm writing a program in C (with a school-specific IDE), then converting it to C++ in Visual Studio. The program in C takes a long variable as user input of 371449635398431 (using the school IDE and a unique compiler function called get_long) When I copy this to Visual Studio, using cin >> instead of get_long, it interprets the long as 2147483647 unless I make it a long long in VS. Are longs in C different than longs in C++ (with longs in C being equivalent to long long in C++?), or could a compiler mismatch be causing the issue?

3 Answers

The C and C++ standards say that a long must have a range of at least -2147483647 to +2147483647. (Note that C++20 requires -2147483648 as the minimum).

Microsoft's compiler for Windows has the range for a long set to -2147483648 to +2147483647. A typical Unix compiler (gcc on rhel for example) has a 64 bit type for a long.

The motivation for keeping the long as a 32 bit type on Windows 64 bit was for backward compatibility. It was really easy to convert Win32 applications to Win64 applications, back in the day.

When the first C Standard was written, it was common for compilers to interpret "long" as the shortest type with at least 32 bits. When compilers added support for 64-bit types, it was common for "long long" to be the shortest type with at least 64 bits. Treating things in this way meant that the lack of fixed-length types wasn't really a problem, since code needing a 32-bit type could use "long" on any platform that had a 32-bit integer type.

MSVC has always followed that convention, even when targeting 64-bit platforms. Some other compilers, however, have decided to change the meaning that long had always had on microcomputer-based platforms, so that instead of long being 32 bits and long long being 64 bits, both would be 64-bit types.

Note, btw, that even on platforms where long and long long are both 64-bit types, they're not compatible with each other. If one has some functions that operate on data identified via long*, and others that operate on data identified via long long*, both clang and gcc will assume that those pointers will never be used to access the same storage.

The size of long depends of compiler, settings, data model and phase of moon (the last reason is a joke). But the long size is at least 32 bit.

If you want to use exact size you can use int64_t. for example.

Related