I can't find out the intention of the following part of printf
specification at cppreference.com:
There is a sequence point after the action of each conversion specifier; this permits storing multiple %n results in the same variable and printing the value stored by %n earlier within the same call.
This reads as if the result of one (or even several) %n
conversion specifier(s) could be printed out in the same printf
-statement.
But I can't find out how this could ever be achieved, because all arguments passed to a call of printf
are evaluated before printf
's body is entered (there is a sequence point after argument evaluation). Hence, the value of a variable to which a %n
would write is evaluated before printf
has the chance to overwrite this variable's value with the "number of characters written so far":
#include <stdio.h>
int main( int argc, char* argv[] )
{
int n = 0;
printf("Hello, world!%n (%d first n); %n (%d second n)", &n ,n, &n, n);
// will print out "Hello, world! (0 first n); (0 second n)"
return 0;
}
My question: If there isn't any chance of "printing the value stored by %n earlier within the same call", isn't then the respective part of the printf
specification senseless or misleading?
What is the actual sense of the c99 standard statement:
7.19.6 Formatted input/output functions (1) The formatted input/output functions shall behave as if there is a sequence point after the actions associated with each specifier.
Is it to reduce the "chances" of getting undefined behaviour?
The question is tagged with c++ and c, because I think that this topic applies the same way to both languages.
In C printf(), %n is a special format specifier which instead of printing something causes printf() to load the variable pointed by the corresponding argument with a value equal to the number of characters that have been printed by printf() before the occurrence of %n.
%d stands for decimal and it expects an argument of type int (or some smaller signed integer type that then gets promoted). Floating-point types float and double both get passed the same way (promoted to double ) and both of them use %f .
%s is for string %d is for decimal (or int) %c is for character.
What does the "f" in printf stand for? The "f" in printf is short for "formatted" and indicates that the text printed to the screen will be formatted. 2. In the Linux command line, printf is a command that inserts arguments into a user-defined string of text, creating formatted output.
This might be crazy, but I think the following is legal:
char s[2];
s[1] = '\0';
printf("Hi, world!%hhn%s", s, s);
%hhn
takes a pointer to char. It writes 10
(the number of characters written so far) to s[0]
. It then prints the string s
, which is equivalent to "\n"
or (char[]){ 10, 0 }
(assuming ASCII).
Your code does indeed only print zeros for the reasons you have identified correctly.
The statement in the Standard is still necessary because of blanket wording elsewhere that the behaviour of the program is undefined if an object is written to more than once without intervening sequence point. In effect, the statement is necessary to say that your code does not have undefined behaviour (unlike, say, i = i++;
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With