2

Why does the following code write four bytes when run on my local Windows machine using Visual C++, yet writes 4 extra 0 bytes when I upload to my school's Unix server?

unsigned long temp = 1025;
ofstream file("test", ofstream::binary);
file.write((char*)&temp, sizeof(temp));

Here is the result using xxd locally: 0104 0000

Here is the result on the Unix server: 0104 0000 0000 0000

Is this a problem with what mode I am opening the file in?

Zach
  • 237
  • 4
  • 16

1 Answers1

4

long has implementation-defined size. Your Windows system uses a 32 bit (4 byte) long (even 64 bit Windows uses 32 bit long; otherwise it's rare to see on 64 bit OSes), while most if not all 64 bit UNIX-like systems I'm aware of have 64 bit (8 byte) longs. Since you're writing out sizeof(temp) bytes, and temp is unsigned long, you'll get different output sizes on different systems (you may also encounter byte order issues if you move from little endian to big endian machines).

If you need a consistent size, use the fixed width types from <cstdint>, e.g. uint32_t or uint64_t.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • To be pedantic, the size of any data type in C++ is a feature of the C++ compiler, not the operating system. There is nothing preventing a compiler from providing 64-bit longs on Windows. –  Jun 15 '18 at 21:30
  • Worth noting that the C++ standard only has a hard specification for the minimum size of the fundamental integer types. The standard also guarantees that the size of a type will be no larger than the next integer type up. This means it is entirely possible (though unlikely) to have `char`, `short`, `int`, `long` and `long long` all the same size, and at least 64 bit. – user4581301 Jun 15 '18 at 21:32
  • For further info, you'd want to compare and contrast [the ILP32 model](https://docs.oracle.com/cd/E19620-01/805-3024/lp64-1/index.html) (common to most 32 bit systems) with [the various 64 bit data models](https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models). – ShadowRanger Jun 15 '18 at 21:32
  • @NeilButterworth: Except ultimately, if you use any of the Windows API that's based on `long`s, you'll have serious problems if your compiler is using 64 bit `long`s, while WinAPI calls continue to expect 32 bit `long`s (unless the compiler is going to extra trouble to perform fixups, wrap WinAPI calls in a runtime adaptor layer, what have you). Yes, it's possible, but clearly the OP isn't in one of those weird cases, as evidenced by their program's behavior. – ShadowRanger Jun 15 '18 at 21:35
  • Well, that's why I said "to be pedantic" :-) –  Jun 15 '18 at 21:36
  • @user4581301: Yup, that's why I was looking up the links to the various data models to make it clear how weird it can get. SILP64 is *strange* (I've worked on a Cray that behaved that way; sadly, I was porting code off it, and the original developers had been seriously lax in their data type choices because it didn't matter on the Crays). – ShadowRanger Jun 15 '18 at 21:37