0

I recently learnt that printf() returns the number of characters it is called to print. But I was wondering I never "used" this return value before, like:

int c = printf("Called func\n");

or

printf("%d", printf("Called func\n"));

I simply wrote statements where the function of printf was performed like:

printf("Called func\n");

So what "happened" to the return value of printf()? How does the compiler know its "ok" to not use the returned integer?

LoveOfLearning
  • 215
  • 3
  • 10
  • 1
    "*How does the compiler know its "ok" to not use the returned integer?*" you told it by coding `printf( ...);`. – alk Jan 01 '18 at 13:23
  • @alk Why doesn't the compiler throw an error, since I called the function "wrongly"? – LoveOfLearning Jan 01 '18 at 13:27
  • 3
    From the formal language perspective it's not wrong to call a function and ignore the value it "returns", it evaluates to. Please see [Basile's answer](https://stackoverflow.com/a/48050046/694576) below. – alk Jan 01 '18 at 13:30
  • 1
    Any simple expression is a valid statement. Calling a function with return value is an expression. Just the same as writing `5;` or `(strcmp);` The compiler might issue some warning aboud expression without sideffect or similar, but it is perfectly OK to ignore any expression. – Gerhardh Jan 01 '18 at 14:43

1 Answers1

6

An expression-statement like

 printf("x=%d\n", x);

is similar to

(void) printf("x=%d\n", x);

the value given by printf is computed (number of characters successfully output, or -1 on error), then discarded and ignored.

BTW, it is the same for an assignment like x=5; : the value (5) of that assignment expression x=5 is discarded and ignored; of course its side-effect is done, of changing the value in the location for variable x. If you coded printf("x=%d\n", (x=5)) the value of that assignment would be used and passed to printf.

An optimizing compiler might (or not) generate slightly different machine code (see as-if rule, at least for C++). But the C11 language specification (read n1570) defines in English wording the observable behavior of your program, i.e. its semantics.

Notice that GCC (and some other compilers, e.g. Clang), provides, as an extension, the ability to declare a function with the warn_unused_result function attribute. You'll then get a warning if the result of that function is not explicitly used.

Notice that some programming languages (Ocaml, Scheme, Haskell, ....) don't have statements, and everything there is an expression, some of them having a side-effect.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Why do you say the value (5) of the statement `x=5;` is discarded and ignored? Isn't the value (5) stored in the memory location intended to be the variable `x`? How is it discarded? Sorry if this is a silly question. – LoveOfLearning Jan 01 '18 at 13:32
  • 1
    It is stored, and 5 is the value of the `x=5` expression, whose important side-effect is to change the value inside the location of variable `x` – Basile Starynkevitch Jan 01 '18 at 13:35
  • 3
    @Truth-seek: You could have done `y = (x = 5) + 1;` which would have set `y` to `6`. – alk Jan 01 '18 at 13:38
  • @alk Thanks. So much insight is ignored where they teach me – LoveOfLearning Jan 01 '18 at 14:30