when I try to compile fprintf(stderr,Usage)
on Ubuntu I got this error:
error: format not a string literal and no format arguments [-Werror=format-security
but when I compiled that on other linux distributions (RedHat, Fedora, SUSE) that is compiled successfully.
Anyone has an idea?
You should use fputs(Usage, stderr);
There is no need to use fprintf if you arn't doing formatting. If you want to use fprintf, use fprintf(stderr, "%s", Usage);
The default compiler flags on Ubuntu includes -Wformat -Wformat-security
which is what gives this error.
That flag is used as a precaution against introducing security related bugs, imagine what
would happen if you somehow did this:
char *Usage = "Usage %s, [options] ... ";
...
fprintf(stderr, Usage);
This would be the same as
fprintf(stderr, "Usage %s, [options] ... ]");
which is wrong.
Now the Usage
string includes a format specifier, %s
, but you do not provide that argument to fprintf
, resulting in undefined behavior, possibly crashing your program or allowing it to be exploited. This is more relevant if the string you pass to fprintf comes from user input.
But if you do fprintf(stderr,"%s", "Usage %s, [options] ... ]");
There is no such problem. The 2. %s
will not be interpreted as a format specifer.
gcc can warn about this, and the default Ubuntu compiler flags makes it a compiler error.
Use fputs(Usage)
or fprintf(stderr, "%s", Usage)
. The idiom of passing a message string to a printf
-family function is dangerous because, unless it's known not to contain format specifiers, any possible format specifiers in the string will be interpreted and result in undefined behavior (since they have no arguments corresponding to them), and this will almost always translate into security bugs.
It is perfectly correct to use fprintf()
with only two arguments. As the function definition clearly indicates, all arguments after the second are optional.
When the second argument does not contain a format clause, this warning actually becomes a bug, one that was introduced into GCC because of a BAD assumption that the second argument to fprintf()
would always contain a format clause. There is nothing that is true about that assumption. This was a flawed decision, a bug, that was repaired in newer versions of GCC, which actually inspect the second argument to ensure the proper number and types of additional arguments are present when required.
Mixing fputs()
and fprintf()
calls is asking for bugs. Plus it just makes the code uglier. It is much cleaner to use fprintf()
everywhere, so long as you are also using a recent and sane GCC.
The moral of this story is simple: Never modify good code to make a bad compiler happy.