warning: format not a string literal and no format arguments

57,664

Solution 1

This warning is gcc's way of telling you that it cannot verify the format string argument to the printf style function (printf, fprintf... etc). This warning is generated when the compiler can't manually peek into the string and ensure that everything will go as you intend during runtime. Lets look at a couple of examples.

Case 1. This string can be verified at compile time and the compiler will allow it without warning:

printf("This string has no format");

Case 2: For this case, the compiler can detect that you have a format specifier and will raise a different warning. On my machine it said "warning: too few arguments for format".

// This will most probably crash your machine
printf("Not a safe string to %s"); 

Case 3. Now this is somewhat your case. You are taking a string generated at runtime and trying to print it. The warning you are getting is the compiler warning you that there could be a format specifier in the string. Say for eg "bad%sdata". In this case, the runtime will try to access a non-existent argument to match the %s. Even worse, this could be a user trying to exploit your program (causing it to read data that is not safe to read).

char str[200];
scanf("%s", str)
printf(str)

Solution 2

While technically there's nothing wrong with calling a printf-like function with a string, it is still bad practice because the string may contain format tokens like %s. If imp is %s test for example, bad things will happen.

If you just want to print the imp without formatting, you should use fputs(imp, fil) (note the reversed arguments).

Solution 3

I think the accepted answer explained it very well. Basically, as the documentation also indicates, the compiler can not guarantee that the string variable (in this case imp) is a string literal. You may disable this warning if you are not concerened with safety by puting

#ifdef _WIN32
#pragma warning (disable : 4774)
#endif

in the header of your code or in the CMake:

if (CMAKE_C_COMPILER_ID STREQUAL "MSVC")
  set(CMAKE_C_FLAGS "/wd4774") 
endif()
Share:
57,664
Unzi
Author by

Unzi

Updated on July 09, 2022

Comments

  • Unzi
    Unzi almost 2 years

    I want to remove the warning that i get on this line of the code,

    FILE *fil;
    char *imp;
    (...)
    fprintf(fil,imp);
    

    the thing is when i do this it writes on the file exactly what i want, but if i apply the format %s it doesn't, like this

    fprintf(fil, "%s", imp);
    
    • casablanca
      casablanca over 13 years
      What does imp contain?
    • pmg
      pmg over 13 years
      What happens if you substitute the fprintf with fputs(imp, fil);?
    • Unzi
      Unzi over 13 years
      a string, lets suppose something like this imp="test";
    • casablanca
      casablanca over 13 years
      @Unzi: If imp doesn't contain any format specifiers (i.e. %...) then both your calls will work the same. What exactly are you observing? What do you mean by "if i apply the format %s it doesn't"?
    • JeremyP
      JeremyP over 13 years
      What do you mean by "it doesn't lke this"? The compiler errors? You don't see any output? What?
    • Unzi
      Unzi over 13 years
      thanks guys problem solve, i have to say i quite new at this, and about the output was writing in the file strange characters.
  • terminus
    terminus over 13 years
    Calling a function which expects a const char * and giving it a char * wouldn't cause a warning, IMHO
  • Sonny Saluja
    Sonny Saluja over 13 years
    I was not suggesting that the string be cast to const. I was mentioning that the second argument needs to be specified to fix the warning.
  • UncleBens
    UncleBens over 13 years
    What do you mean by having to "specify an argument"?
  • ollb
    ollb over 13 years
    Even worse: if the user can specify the imp string, he may be able to use the %n format token to overwrite memory. This is known as format string attack and may be used to run injected code.
  • Kris Krause
    Kris Krause over 12 years
    fputs does the trick to write out a string sans % formatting.
  • SasQ
    SasQ almost 12 years
    @Sanjit Saluja: Great explanation. So how to tell GCC that I know what I'm doing to suppress that warning?
  • Sonny Saluja
    Sonny Saluja over 11 years
    Look at compiler flag -Wno-format here gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Warning-Options.html. You can perhaps try (#pragma GCC diagnostic ignored "-Wformat") in the file to see if you disable the warning for that file only
  • TheRookierLearner
    TheRookierLearner about 10 years
    So how do (safely) you handle a string containing a format specifier? Say I am downloading a html file from the web using libcurl and that file might contain "%s" somewhere. How do I handle that?
  • Nick
    Nick over 8 years
    'sans' is French for 'without'. Does he mean "without % formatting" ?
  • Nils_M
    Nils_M about 7 years
    To avoid the warning and possible attack vectors you can also use printf("%s", str);.