2

I am having a compilation error on the following code:

printf((char *) buffer);

and the error message that I am getting is:

cc1: format not a string literal and no format arguments...

I suspect there are some libraries that I forgot to install, as I was able to compile and run the code without an error on the other machine...

PS: The question rises with the fact that I was able to run the same code on some other machine... I suspect a difference in gcc version might cause a problem like this?

4
  • The text of this sounds very much like it should be a warning and not an error. Can you give more information about the compiler that you are using and what options you are using? Commented Jul 22, 2009 at 19:53
  • post the definition of 'buffer' Commented Jul 22, 2009 at 19:56
  • My memory's a bit hazy on this, but it's often possible to promote warnings to errors. Commented Jul 22, 2009 at 19:57
  • Charles, you are right about that (gcc 4.2.4, the one that I've been using before have greater tolerance against printf((char *) buffer) and throw a warning instead of an error. gcc 4.3.3 on the otherhand considers this as an error Commented Jul 22, 2009 at 20:07

4 Answers 4

5

Newer GCC versions try to parse the format string passed to printf and similar functions and determine if the argument list correctly matches the format string. It can't do this because you've passed it a buffer for the first argument, which would normally be a format string.

Your code is not incorrect C, it's just a poor usage of C. As others mentioned you should use "%s" as a format string to print a single string. This protects you from a class of errors that involve percentage signs in your string, if you don't control the input. It's a best practice to never pass anything but a string literal as the first argument to the printf or sprintf family of functions.

Sign up to request clarification or add additional context in comments.

1 Comment

I think you nailed the problem :)
4

try

printf("%s", (char*) buffer);

;-)

8 Comments

The question rises with the fact that I was able to run the same code on some other machine... I suspect a difference in gcc version might cause a problem like this?
well it sounds like that other machine isn't standard C
printf(%s) is bad practice as you're very likely to trash the stack if your string contains any special characters (%d, %s, etc.). The first argument of printf should always be a string literal. I'm guessing different versions of GCC are more strict about whether or not they'll allow you to do it.
They have to allow it, or they aren't conforming C compilers. They don't have to like it.
They allow it, they just give a warning when that happens (and they are in their right as a conformant implementation). And he is most likely compiling with "treat warnings as errors".
|
1

This warning is generated by gcc if

-Wformat-nonliteral

is set. It's not part of -Wall or -Wextra (at least for version 4.4.0), so just drop it if you want the code to compile warning-free.

Comments

0

This is a warning for your safety, not an error. This new compiler is apparently being more strict about it. I don't think it's actually illegal in C, so the compiler should have an option to disable treating this as an error.

However, you pretty much never want to pass anything other than a string literal as the first argument to printf. The reason that doing so is such a horrible idea that the compiler has a special built-in check to warn you about it is this: Suppose the non-literal string that you pass as the first argument to printf happens to contain printf formatting characters. printf is then going to try to access second, third, fourth, etc, arguments that you didn't actually pass in, and may well crash your program by trying to do so. If the non-literal first argument is actually user-supplied, then the problem is even worse since a malicious user could crash your program at will.

1 Comment

Usually, you can do what you want to do with a string literal for a format string, particularly since the rest of the statement is fixed at compile time. There may be cases where it's preferable to pass in a non-literal string, but as Tyler points out this is a dangerous practice, and you should never under any circumstances use user input this way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.