Search code examples
clocaleprintfnumber-formattingicc

Warning using ICC and printf with thousands grouping format (apostrophe)


I need to display some numbers with thousands grouping (in this case, using period as separator). So, I'm using the printf flag ' to achieve such thing.

With gcc everything goes well, but if I use icc, then I get this warning:

warning #269: invalid format string conversion

despite the fact that the number is indeed printed with the desired format.

For example, if we compile this simple program:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main(int argc, char *argv[]) {
    setlocale(LC_NUMERIC, "da_DK");
    int i = 12345678;
    unsigned long int j = 987654321;

    printf("%d \t %'d \n%lu \t %'lu \n", i, i, j, j);
}

then we get this warning:

% icc -o simple simple.c 

simple.c(10): warning #269: invalid format string conversion
  printf("%d \t %'d \n%lu \t %'lu \n", i, i, j, j);
                                          ^

despite the fact that everything works as expected:

% ./simple 
12345678         12.345.678 
987654321        987.654.321 

So my questions are:

  1. How can this warning be suppressed?
  2. Is it safe to use ' as flag with printf and friends, with the icc compiler?

UPDATE:

I've just realized that an strange trick to suppress the 269 warning is defining a variable with the format, and pass that variable to printf:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main(int argc, char *argv[]) {
    setlocale(LC_NUMERIC, "da_DK");
    int i = 12345678;
    unsigned long int j = 987654321;
    const char *strFormat = "%d \t %'d \n%lu \t %'lu \n";

    printf(strFormat, i, i, j, j);
}

UPDATE:

Because using apostrophe with printf is an XSI Extension (as stated by @Dave), in order to make the code more portable may be more useful to follow the recommendation from the C-FAQ, question 12.11 and use their implementation of commaprint.


Solution

  • To answer your second question, The compiler doesn't actually control the processing of your format string; that's your C library's job. icc doesn't recognize the format string because it is nonstandard, but as long as you understand that your code will only be valid on platforms whose c libraries support the ' flag, you'll be ok.

    As the opengroup page shows, ' is an XSI extension, so your code will work on any XSI-conformant platform.