2
votes

When I compile my code under Linux x64 (under x86 no warning) I get the following warning warning: format ‘%llx’ expects argument of type ‘long long unsigned int *’, but argument 3 has type ‘off64_t *’ [-Wformat]

my code snippet:

if(maps && mem != -1) {
        char buf[BUFSIZ + 1];

        while(fgets(buf, BUFSIZ, maps)) {
                off64_t start, end;

                sscanf(buf, "%llx-%llx", &start, &end);
                dump_region(mem, start, end);
        }
}

How should I cast it to get no warning?

EDIT:

Should I cast like this?:

sscanf(buf, "%llx-%llx", (long long unsigned int *)&start, (long long unsigned int *)&end);
2
use PRIu64 instead of %llxGrijesh Chauhan
check this how to use it is a macro.Grijesh Chauhan
something like sscanf(buf, "%"PRIu64"-%"PRIu64, &start, &end); ? compiles with no warning but the code doesn't work now.bsteo
yes but what is in buffer, notice you are using - in scanf that is the reason I didn't post an answer. buff should be as "3223-2254"Grijesh Chauhan
@Grijesh Chauhan For types >= sizeof(int), I would expect the formats to be the same. Maybe not for smaller types? Do not have a handy link.chux - Reinstate Monica

2 Answers

2
votes

2 approaches come to mind using sscanf() to read a non-standard integer types like off64_t.

1) Try to divine the correct format specifier through various conditions (#if ...) and use sscanf(). Assuming it is SCNx64 below

 #include <inttypes.h>
 off64_t start, end;
 if (2 == sscanf(buf, "%" SCNx64 "-%" SCNx64, &start, &end)) Success();

2) Use sscanf() with the largest int and convert afterwards.

 #include <inttypes.h>
 off64_t start, end;
 uintmax_t startmax, endmax;
 if (2 == sscanf(buf, "%" SCNxMAX "-%" SCNxMAX, &startmax, &endmax)) Success();

 start = (off64_t) startmax;
 end   = (off64_t) endmax;

 // Perform range test as needed
 if start != startmax) ...

BTW: Suggestions to use PRI... should be SCN... for scanf(). PRI... is for the printf() family.

Always good to check sscanf() results.

0
votes

Seems the best way I could find so far is casting:

#if __GNUC__
  #if __x86_64__ || __ppc64__
    #define ENV64BIT
    #define _LARGEFILE_SOURCE
    #define _FILE_OFFSET_BITS 64
  #else
    #define ENV32BIT
  #endif
#endif

then

#if defined(ENV64BIT)
    sscanf(buf, "%llx-%llx", (long long unsigned int *)&start, (long long unsigned int *)&end);
#else
    sscanf(buf, "%llx-%llx", &start, &end);
#endif