6

I understand that if printf is given no arguments it outputs an unexpected value.

Example:

#include <stdio.h>

int main() {
    int test = 4 * 4

    printf("The answer is: %d\n");
    return 0;
}

This returns a random number. After playing around with different formats such as %p, %x etc, it doesn't print 16(because I didn't add the variable to the argument section) What i'd like to know is, where are these values being taken from? Is it the top of the stack? It's not a new value every time I compile, which is weird, it's like a fixed value.

sbnation
  • 149
  • 2
  • 9
  • 2
    It's undefined behavior. The fact that it seems fixed is a happy accident. It may be coming from the stack, maybe from a register... you don't know, shouldn't care or count on it. – Paul Roub Dec 26 '14 at 18:30
  • 1. With `printf("The answer is: %d\n")`, you are passing **one** argument. 2. If that argument points to a null-terminated string which does not contain a `%` character, then `printf` will output a well-expected value. – barak manos Dec 26 '14 at 18:34

4 Answers4

5
printf("The answer is: %d\n");

invokes undefined behavior. C requires a conversion specifier to have an associated argument. While it is undefined behavior and anything can happen, on most systems you end up dumping the stack. It's the kind of trick used in format string attacks.

ouah
  • 142,963
  • 15
  • 272
  • 331
5

It is called undefined behavior and it is scary (see this answer).

If you want an explanation, you need to dive into implementation specific details. So study the generated source code (e.g. compile with gcc -Wall -Wextra -fverbose-asm + your optimization flags, then look into the generated .s assembly file) and the ABI of your system.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

The printf function will go looking for the argument on the stack, even if you don't supply one. Anything that's on there will be used, if it can't find an integer argument. Most times, you will get nonsensical data. The data chosen varies depending on the settings of your compiler. On some compilers, you may even get 16 as a result.

For example:

int printf(char*, int d){...}

This would be how printf works(not really, just an example). It doesn't return an error if d is null or empty, it just looks on the stack for the argument that's supposed to be there to display.

Orange Mushroom
  • 431
  • 4
  • 16
1

Printf is a variable argument function. Most compilers push arguments onto the stack and then call the function, but, depending on machine, operating system, calling convention, number of arguments, etc, there are also other values pushed onto the stack, which might be constant in your function.

Printf reads this area of memory and returns it.

gbronner
  • 1,907
  • 24
  • 39