I came across this program via a quora answer
我通过quora答案看到了这个程序
#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?
我想知道这是如何工作的,如果这符合标准?
3 个解决方案
#1
7
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.
此代码使用名为statement-expressions的“GNU C”功能,其中括号括起的复合语句可用作表达式,其类型和值与复合语句中最后一个语句的结果相匹配。这不是语法上有效的C,而是一个GCC特性(也被一些其他编译器采用),这可能是因为它被认为对编写不会多次评估其参数的宏很重要。
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.
如果你在必须阅读的代码中遇到它,你应该知道它是什么以及它做了什么,但我会避免自己使用它。这是令人困惑,不必要和非标准的。使用静态内联函数几乎总能实现相同的功能。
#2
0
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.
我不相信它确实有效... n在括号内有本地范围...当你退出大括号时,n变得未定义虽然我认为它仍然可以存在于堆栈的某个位置并且可能有效。它正在乞求实施问题,我保证是依赖于实现的。
One thing I can tell you is that anyone working for me who wrote that would be read the riot act.
我可以告诉你的一件事是,任何为我写作的人都会读到*行为。
#3
0
It works. I get no warnings from gcc, so I suppose that it conforms to the standard.
有用。我没有得到gcc的警告,所以我认为它符合标准。
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.
这个块从控制台扫描一个整数(没有错误检查)并将其平方,返回平方数。在C的古老实现中,返回堆栈上的最后一个数字。 n * n将数字放在堆栈上。
That value gets passed to the printf:
该值传递给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.
所以,回答你的问题:是的,它有效。是的,这是“标准”(在某种程度上,任何人都完全遵循标准)。不,这不是一个很好的做法。这是一个很好的例子,我用膝跳反应称之为“编译器情书”,主要是为了表明程序员有多聪明,不一定要解决问题或高效。
#1
7
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.
此代码使用名为statement-expressions的“GNU C”功能,其中括号括起的复合语句可用作表达式,其类型和值与复合语句中最后一个语句的结果相匹配。这不是语法上有效的C,而是一个GCC特性(也被一些其他编译器采用),这可能是因为它被认为对编写不会多次评估其参数的宏很重要。
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.
如果你在必须阅读的代码中遇到它,你应该知道它是什么以及它做了什么,但我会避免自己使用它。这是令人困惑,不必要和非标准的。使用静态内联函数几乎总能实现相同的功能。
#2
0
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.
我不相信它确实有效... n在括号内有本地范围...当你退出大括号时,n变得未定义虽然我认为它仍然可以存在于堆栈的某个位置并且可能有效。它正在乞求实施问题,我保证是依赖于实现的。
One thing I can tell you is that anyone working for me who wrote that would be read the riot act.
我可以告诉你的一件事是,任何为我写作的人都会读到*行为。
#3
0
It works. I get no warnings from gcc, so I suppose that it conforms to the standard.
有用。我没有得到gcc的警告,所以我认为它符合标准。
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.
这个块从控制台扫描一个整数(没有错误检查)并将其平方,返回平方数。在C的古老实现中,返回堆栈上的最后一个数字。 n * n将数字放在堆栈上。
That value gets passed to the printf:
该值传递给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.
所以,回答你的问题:是的,它有效。是的,这是“标准”(在某种程度上,任何人都完全遵循标准)。不,这不是一个很好的做法。这是一个很好的例子,我用膝跳反应称之为“编译器情书”,主要是为了表明程序员有多聪明,不一定要解决问题或高效。