I wrote a complete application on C99 and tested it thoroughly on two GNU / Linux based systems. I was surprised when trying to compile it using Visual Studio on Windows caused the application to malfunction. At first, I could not say what was wrong, but I tried to use the VC debugger, and then I found that the fscanf() function declared in stdio.h did not fscanf() .
The following code is enough to demonstrate the problem:
#include <stdio.h> int main() { unsigned num1, num2, num3; FILE *file = fopen("file.bin", "rb"); fscanf(file, "%u", &num1); fgetc(file); // consume and discard \0 fscanf(file, "%u", &num2); fgetc(file); // ditto fscanf(file, "%u", &num3); fgetc(file); // ditto fclose(file); printf("%d, %d, %d\n", num1, num2, num3); return 0; }
Suppose file.bin contains exactly 512\0256\0128\0 :
$ hexdump -C file.bin 00000000 35 31 32 00 32 35 36 00 31 32 38 00 |512.256.128.|
Now that it compiles to GCC 4.8.4 on an Ubuntu machine, the resulting program reads the numbers as expected and prints 512, 256, 128 to stdout.
Compiling with MinGW 4.8.1 on Windows gives the same expected result.
However, it seems that there is a big difference when compiling code using Visual Studio Community 2015; namely:
512, 56, 28
As you can see, trailing null characters have already been used by fscanf() , so fgetc() captures and discards characters that are necessary for data integrity.
Commenting out the lines of fgetc() , the code works in VC, but splits it into GCC (and, possibly, to other compilers).
What is going on here, and how do I turn this into portable C code? Did I hit undefined behavior? Please note that I accept the C99 standard.