What is wrong with printf("%llx")?

Untitled picture Untitled · Dec 28, 2012 · Viewed 24k times · Source

I have this piece of code that is challenging all my knowledge of C. Here I have :

int main(void){
    unsigned long long int massage ;

    scanf("%llX", &massage); //input: 0x1234567890abcdef
    printf("%llX", massage);
    return 0;
}

On my "64bit - Corei5 - Fedora - GCC" it prints out exactly what I fed it. but on my buddy's system (32bit, MS XP, MinGW) it prints 90ABCDEF. I don't understand why. does anyone know?

BTW: sizeof(unsigned long long int) on his system is 8.

Answer

ruakh picture ruakh · Dec 28, 2012

The issue is a discrepancy between what the compiler believes (as reflected in sizeof: sizeof(unsigned long long int) is evaluated at compile-time) and what the run-time library believes (as reflected in printf: the printf function is called at run-time, so that's when its format-specifiers take effect).

According to "C99" in the MinGW documentation:

GCC does not include a C runtime library. This is supplied by the platform. The MinGW port of GCC uses Microsoft's original (old) Visual C runtime, MSVCRT, which was targeted by Microsoft Visual Studio 6 (released in 1998).

[…]

Because MinGW relies on MSVCRT, it has many of the same limitations and quirks with compatibility as Visual Studio 6. You should assume that MinGW applications cannot rely on C99 behaviour, only on C89. For example, the newer format characters in printf like %a and %ll are not supported, although there exists a workaround for %ll.

(The workaround that it mentions is to use I64 instead of ll: so, %I64X. Annoyingly, at least on my system, GCC will issue a warning when it sees that in a literal format-string, because it assumes it'll have a better run-time library.)