我做了一个for循环,在每次迭代中检查索引是否等于整数,我意识到我可以写一个很长的if语句,使它比现在更可读。我想知道在if语句中包含100个条件是否有任何明确的规则或未定义的行为、限制或缺点:
for
if
&&
||
9avjhtql1#
我想知道根据C99标准在if语句中有100个条件是否有任何明确的规则或未定义的行为、限制或缺点不,没有明确的规则或未定义的行为。(有很多限制和缺点,在这个问题的其他答案和评论中详细讨论过,但这些都是风格,不是编译器会关心的任何东西。在现代x64 Intel机器上编译,带有最新的gcc如果你的问题是关于C99标准定义的语言,那么你使用的编译器并不重要。一方面,这对计算机程序来说并不罕见(包括编译器)有各种限制,不能对完全无界的输入进行操作。但另一方面,它一直在某种程度上是C哲学的一部分,绝对是GNU/FSF哲学的一部分,尽可能地避免任何和所有任意的限制。所以如果我听到gcc有你所问的那种限制,我会非常惊讶。我构造了一个“简单的”if语句,其格式如下:
if(a1 == b1 && a2 == b2 && a3 == b3 && … && a98 == b98 && a99 == b99 && a100 == b100)
我在gcc的两个版本(4.6.3和10.2.1)下测试了它,有-std=c99和没有-std=c99,没有得到任何错误(但我没有测试生成的代码以确保它完美地工作)。正如Eric Postpischil在他的回答中提到的,如果一个编译器编译了一个没有错误的复杂表达式,但是生成了行为不正确的代码,这将是非常令人惊讶的。这是(谢天谢地)在实践中罕见的失败模式。
-std=c99
hpcdzsge2#
我想知道是否有任何明确的规则或未定义的行为,限制,…C 1999 5.2.4 1说:“翻译和执行环境都限制了语言翻译器和库的实现......”这意味着编译器不需要能够编译每一个理论上符合任何长度的C程序。当给定的程序包含太多复杂的各种类型时,它可能会失败。5.2.4.1 1指定了符合C实现必须能够支持的最小阈值,尽管指定的很弱,因为实现应该能够翻译和执行一个满足所有阈值的程序。这些阈值都与具有100个条件的if没有直接关系。可能影响它的两个是:
hgqdbh6s3#
C99和C11标准(C99 §5.2.4.1平移限值;C11 §5.2.4.1平移限值)表示:该实现应能够翻译和执行至少一个程序,该程序至少包含以下限制中的每一个的一个示例:
18)实现应该尽可能避免强加固定的转换限制。脚注19指出了关于标识符最大长度的“未来方向”,指出任何小于255的长度都应被视为过时。同样的限制适用于C18(C17)和C23的最新草案。这些限制都不直接适用于您所描述的场景,在描述你的场景的范围内。最有可能应用的是“完整表达式中括号表达式的63个嵌套级别”。“逻辑行长度”限制可以通过在标记对之间添加换行符来规避。只是不要创建任何长于行长度限制的标识符-但是标识符将是完整的论文,因此完全不切实际。整个答案只有4KiB多一点。因此,即使是一个非常复杂的if条件,编译器也不太可能有任何问题。“只有”100个条件不太可能破坏它。然而,任何人如果能理解一个if条件中包含100个条件的代码,那他就是一个奇迹创造者(或者可能是一个骗子)。
if (strcmp(a, "ABC") == 0 || strcmp(a, "BCD") == 0 || … )
如果条件非常多样化,或者如果有嵌套的条件(||和&&的混合,加上括号,可能还有一些否定运算符),那么人们就不会理解代码。
IMNSHO,你的座右铭应该是“不要这样做!”必须有更好的方法来处理你正在测试的任何东西。替代方法包括循环和函数。编译器限制应该很少,如果有的话,是你关心的。当他们关心时,通常有某种代码结构问题。例如,如果你有一个需要128个参数的函数,而你的编译器遵循标准规定的下限(127),那么你的数据结构化得不是很好-你可能应该使用结构类型来将其中的一些参数组合在一起。
3条答案
按热度按时间9avjhtql1#
我想知道根据C99标准在if语句中有100个条件是否有任何明确的规则或未定义的行为、限制或缺点
不,没有明确的规则或未定义的行为。(有很多限制和缺点,在这个问题的其他答案和评论中详细讨论过,但这些都是风格,不是编译器会关心的任何东西。
在现代x64 Intel机器上编译,带有最新的gcc
如果你的问题是关于C99标准定义的语言,那么你使用的编译器并不重要。
一方面,这对计算机程序来说并不罕见(包括编译器)有各种限制,不能对完全无界的输入进行操作。但另一方面,它一直在某种程度上是C哲学的一部分,绝对是GNU/FSF哲学的一部分,尽可能地避免任何和所有任意的限制。所以如果我听到gcc有你所问的那种限制,我会非常惊讶。
我构造了一个“简单的”
if
语句,其格式如下:我在gcc的两个版本(4.6.3和10.2.1)下测试了它,有
-std=c99
和没有-std=c99
,没有得到任何错误(但我没有测试生成的代码以确保它完美地工作)。正如Eric Postpischil在他的回答中提到的,如果一个编译器编译了一个没有错误的复杂表达式,但是生成了行为不正确的代码,这将是非常令人惊讶的。这是(谢天谢地)在实践中罕见的失败模式。
hpcdzsge2#
我想知道是否有任何明确的规则或未定义的行为,限制,…
C 1999 5.2.4 1说:“翻译和执行环境都限制了语言翻译器和库的实现......”这意味着编译器不需要能够编译每一个理论上符合任何长度的C程序。当给定的程序包含太多复杂的各种类型时,它可能会失败。
5.2.4.1 1指定了符合C实现必须能够支持的最小阈值,尽管指定的很弱,因为实现应该能够翻译和执行一个满足所有阈值的程序。这些阈值都与具有100个条件的
if
没有直接关系。可能影响它的两个是:...
在你的问题中不要提到括号,通过将语句分成多行,很容易避免在逻辑源代码行中出现4095个字符。
......在if语句中有100个条件的缺点是由......
这里的主要问题不是编译器的限制或缺陷,而是糟糕的设计。我对编译器的最低要求是,如果它不能正确编译程序,它会报告。我们应该能够期望,如果编译器生成一个程序,而没有报告编译错误,那么生成的程序将正确执行。
此外,高质量的编译器可能会优化程序并为
if
语句生成好的代码,可能比作者名义上写的更好。然而,在一般的编程中,优化和表达的机会比比皆是。一个有100个条件的
if
语句可能有很多替代设计的可能性。我们可以使用表格来记录和查找哪些情况应该通过或失败测试,而不是将它们硬编码到代码中。或者我们可以使用其他数据驱动的解决方案,比如一个表示待测试条件的树。我们可能会优化测试,尝试首先区分最常见的情况。我们可能会对条件进行数学分析,以简化它们。我们可能会重写条件,使其对人类读者更清晰。hgqdbh6s3#
C标准怎么说
C99和C11标准(C99 §5.2.4.1平移限值;C11 §5.2.4.1平移限值)表示:
该实现应能够翻译和执行至少一个程序,该程序至少包含以下限制中的每一个的一个示例:
18)实现应该尽可能避免强加固定的转换限制。
脚注19指出了关于标识符最大长度的“未来方向”,指出任何小于255的长度都应被视为过时。
同样的限制适用于C18(C17)和C23的最新草案。
这些限制都不直接适用于您所描述的场景,在描述你的场景的范围内。最有可能应用的是“完整表达式中括号表达式的63个嵌套级别”。“逻辑行长度”限制可以通过在标记对之间添加换行符来规避。只是不要创建任何长于行长度限制的标识符-但是标识符将是完整的论文,因此完全不切实际。整个答案只有4KiB多一点。
因此,即使是一个非常复杂的
if
条件,编译器也不太可能有任何问题。“只有”100个条件不太可能破坏它。然而,任何人如果能理解一个
if
条件中包含100个条件的代码,那他就是一个奇迹创造者(或者可能是一个骗子)。如果条件非常多样化,或者如果有嵌套的条件(
||
和&&
的混合,加上括号,可能还有一些否定运算符),那么人们就不会理解代码。别这么做!
IMNSHO,你的座右铭应该是“不要这样做!”必须有更好的方法来处理你正在测试的任何东西。替代方法包括循环和函数。编译器限制应该很少,如果有的话,是你关心的。当他们关心时,通常有某种代码结构问题。例如,如果你有一个需要128个参数的函数,而你的编译器遵循标准规定的下限(127),那么你的数据结构化得不是很好-你可能应该使用结构类型来将其中的一些参数组合在一起。