Quixotic
Quixotic

Reputation: 2464

On understanding how printf("%d\n", ( { int n; scanf("%d", &n); n*n; } )); works in C

I came across this program via a quora answer

 #include<stdio.h>
 int main() {
    printf("%d\n", ( { int n; scanf("%d", &n); n*n; } ));
    return 0;
 }

I was wondering how does this work and if this conforms the standard?

Upvotes: 10

Views: 1756

Answers (3)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215201

This code is using a "GNU C" feature called statement-expressions, whereby a parentheses-enclosed compound statement can be used as an expression, whose type and value match the result of the last statement in the compound statement. This is not syntactically valid C, but a GCC feature (also adopted by some other compilers) that was added presumably because it was deemed important for writing macros which do not evaluate their arguments more than once.

You should be aware of what it is and what it does in case you encounter it in code you have to read, but I would avoid using it yourself. It's confusing, unnecessary, and non-standard. The same thing can almost always be achieved portably with static inline functions.

Upvotes: 8

PaulProgrammer
PaulProgrammer

Reputation: 17630

It works. I get no warnings from gcc, so I suppose that it conforms to the standard.

The magic is the closure:

{ int n; scanf("%d", &n); n*n; }

This nugget scans an integer from the console (with no error checking) and squares it, returning the squared number. In ancient implementations of C, the last number on the stack is returned. The n*n puts the number on the stack.

That value gets passed to the printf:

printf("%d\n", <scanned>);

So, to answer your questions: Yes, it works. Yes, it's "standard" (to the extent that anyone follows the standard entirely). No, it's not a great practice. This is a good example of what I by knee-jerk reaction call a "compiler love letter", designed mostly to show how smart the programmer is, not necessarily to solve a problem or be efficient.

Upvotes: 0

K Scott Piel
K Scott Piel

Reputation: 4380

I don't believe it does work... n has local scope within the braces... when you exit the braces, n becomes undefined though I suppose is could still exist somewhere on the stack and might work. It's begging for implementation issues and I guarantee is implementation dependent.

One thing I can tell you is that anyone working for me who wrote that would be read the riot act.

Upvotes: 0

Related Questions