gpt4 book ai didi

c - 即使在不必要的情况下,是否也有反对使用大括号的客观理由?

转载 作者:行者123 更新时间:2023-12-03 13:32:57 25 4
gpt4 key购买 nike

内核编码风格和 gnome 的 C 风格指南都指出:

Do not unnecessarily use braces where a single statement will do.

if (condition)
action();

但同时它 应该有时会使用,如 else分支:
if (condition) {
do_this();
do_that();
} else {
otherwise();
}

是否有任何技术或可用性原因更喜欢这种方式?有什么客观的理由不每次都把牙套放在那里吗?

最佳答案

只有风格和易于编辑相关的原因。
无论是否省略大括号,C 编译器都必须像有大括号一样(+ 一对围绕整个迭代语句( ifif - else ))。
6.8.4p3 :

A selection statement is a block whose scope is a strict subset of thescope of its enclosing block. Each associated substatement is also ablock whose scope is a strict subset of the scope of the selectionstatement.


这些隐式块的存在可以用枚举很好地证明:
#include <stdio.h>
int main()
{
enum{ e=0};
printf("%d\n", (int)e);
if(1) printf("%d\n", (sizeof(enum{e=1}),(int)e));
if(sizeof(enum{e=2})) printf("%d\n", (int)e);
printf("%d\n", (int)e);

//prints 0 1 2 0
}
迭代语句也存在类似的规则: 6.8.5p5 .
这些隐式块还意味着在迭代或选择语句中定义的复合文字仅限于这种隐式块。这就是为什么示例 http://port70.net/~nsz/c/c11/n1570.html#6.5.2.5p15从标准中,将复合文字放在标签和显式 goto 之间而不是简单地使用 while语句,这将限制文字的范围,无论是否使用显式大括号。
虽然它可能很诱人,但永远不要这样做:
if (Ptr) Ptr = &(type){0}; //WRONG way to provide a default for Ptr
由于范围规则,上述导致 UB(实际上是不工作的智慧 gcc -O3)。
执行上述操作的正确方法是:
type default_val = {0};
if (Ptr) Ptr = &default_val; //OK
或与:
Ptr = Ptr ? Ptr : &(type){0}; //OK
这些隐式块在 C99 中是新的,并且内部块(用于选择语句 (=ifs))被很好地合理化( C99RationaleV5.10.pdf,第 6.8 节)作为重构的辅助工具,防止从先前未加括号的分支中添加的花括号改变含义。
不幸的是,围绕整个选择语句的最外层分支似乎没有很好地合理化(更准确地说,它根本没有合理化)。它似乎是从迭代语句的规则复制而来的,它似乎复制了 C++ 规则,其中 for -loop-local 变量在整个 for 循环的最后被销毁(就像 for 循环被加括号一样)。
(不幸的是,我认为对于选择语句,最外层的隐式 {} 弊大于利,因为它阻止您拥有仅在调用方范围内进行堆栈分配但还需要检查的宏,因为那样您只能检查这样的带有 ?: 但不是带有 if 的宏,这很奇怪。)

关于c - 即使在不必要的情况下,是否也有反对使用大括号的客观理由?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60779179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com