Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does gcc(windows + MinGW) defines SCNd8, SCNu8 in inttypes.h?

Tags:

c

gcc

mingw

c99

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    int8_t int8;
    int16_t int16;
    int32_t int32;
    int64_t int64;

    uint8_t uint8;
    uint16_t uint16;
    uint32_t uint32;
    uint64_t uint64;

    scanf("%"SCNd8"%"SCNd16"%"SCNd32"%"SCNd64"%"SCNu8"%"SCNu16"%"SCNu32"%"SCNu64, 
            &int8, &int16, &int32, &int64, &uint8, &uint16, &uint32, &uint64);

    printf("%"PRId8"\n%"PRId16"\n%"PRId32"\n%"PRId64"\n%"PRIu8"\n%"PRIu16"\n%"PRIu32"\n%"PRIu64"\n",
            int8, int16, int32, int64, uint8, uint16, uint32, uint64);

    return 0;
}

I can't compile this code using latest gcc + MinGW + Netbeans + Windows. Netbeans says "unable to resolve identifier SCNd8 and SCNu8". I can't find any reference for SCNd8 and SCNu8 on gcc man page although http://linux.die.net/include/inttypes.h defines them. I don't receive syntax error for using PRId8 or PRIu8.

MinGW inttypes.h (lacks SCNd8 and SCNu8 ) (sample code)

#define PRIXFAST64 "I64X"

#define PRIXMAX "I64X"
#define PRIXPTR "X"

/*
 *   fscanf macros for signed int types
 *   NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t
 *   (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have
 *   no length identifiers
 */

#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 "I64d"

#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 "I64d"

#define SCNdFAST16 "hd"    
like image 908
gameboy Avatar asked Nov 04 '10 21:11

gameboy


2 Answers

Interesting - I have MinGW with GCC Version 4.5.1 installed.

The format specifier macros in inttypes.h work for the most part, except for the the ones for inputting 8-bit ints (SCNd8 and SCNu8). Those macros are defined in inttypes.h, but trying to use them doesn't work so well. With the following code:

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    int8_t int8 = 0;
    uint8_t uint8 = 0;

    scanf("%"SCNd8, &int8);
    scanf("%"SCNu8, &uint8);

    return 0;
}

I get the following warnings:

C:\temp\test.c: In function 'main':
C:\temp\test.c:9:5: warning: unknown conversion type character 'h' in format
C:\temp\test.c:9:5: warning: too many arguments for format
C:\temp\test.c:10:5: warning: unknown conversion type character 'h' in format
C:\temp\test.c:10:5: warning: too many arguments for format

So it seems that GCC 4.5.1 and/or glibc don't support the "%hhd" and "%hhu" C99 format specifiers. If I run this program under a debugger, more than just the byte variables do end up being modified by the scanf() calls.

Just for reference, I'm using the following command to compile:

 "C:\MinGW\bin\gcc" -std=c99 -Wall -g  -Ic:\MinGW\include -D_WIN32_WINNT=0x0500 "C:\temp\test.c"  -lkernel32 -luser32 -lgdi32 -ladvapi32 -lshlwapi -loleaut32 -o "test".exe

Note that the various character-sized int input formats (that use "hh") in inttypes.h only get compiled in if the C99 standard is specified - they're protected by:

#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L

The other format specifiers are compiled in even for C90 compiles.

So you won't get the "hh" formats unless you use the -std=c99 or -std=gnu99 options (but remember that they don't seem to work anyway).


Update:

Of course! The reason the "hhd" and "hhu' specifiers aren't supported is because the MinGW runtime uses the scanf() from Microsoft's msvcrt.dll which doesn't know anything about the new stuff in C99's input formats. If you want to use these input formats, you'll need to use some other scanf() implementation.

As mentioned in MinGW's inttypes.h:

MS runtime scanf appears to treat "hh" as "h"

like image 143
Michael Burr Avatar answered Nov 11 '22 10:11

Michael Burr


You could add the following after #include <inttypes.h>:

#ifndef SCNd8
  #define SCNd8 "hhd"
#endif
#ifndef SCNu8
  #define SCNu8 "hhu"
#endif

Which should be appropriate for most platforms.

Clarification: Where "most platforms" refers to platforms with a C99-compliant fscanf/scanf that can handle the hh prefix for char, not just the h prefix for short.

like image 22
tomlogic Avatar answered Nov 11 '22 12:11

tomlogic