在C99,为f()+ G()未定义或仅仅是不确定的? [英] In C99, is f()+g() undefined or merely unspecified?

查看:96
本文介绍了在C99,为f()+ G()未定义或仅仅是不确定的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以前认为在C99中,即使功能副作用˚F先按g 的干扰,虽然前任pression F()+ G()不包含顺序点,˚F先按g 将包含一些,这样的行为是不确定的:无论是F()将克(),或f之前克()()之前被调用。

I used to think that in C99, even if the side-effects of functions f and g interfered, and although the expression f() + g() does not contain a sequence point, f and g would contain some, so the behavior would be unspecified: either f() would be called before g(), or g() before f().

我不再那么肯定。如果编译器内联(编译器可以决定,即使函数不声明在线做),然后重新安排指令的功能?可能有获得以上两种不同的结果?换句话说,这是不确定的行为?

I am no longer so sure. What if the compiler inlines the functions (which the compiler may decide to do even if the functions are not declared inline) and then reorders instructions? May one get a result different of the above two? In other words, is this undefined behavior?

这是不是因为我打算写这种东西,这就是选择最好的标签在静态分析仪这样的说法。

This is not because I intend to write this kind of thing, this is to choose the best label for such a statement in a static analyzer.

推荐答案

这位前pression F()+ G()包含至少4顺序点;一个调用˚F前()(它的参数都为零后进行评估);一个调用摹前()(它的参数都为零后进行评估);一个作为调用 F()的回报;和一个作为调用克()的回报。此外,随着 F()发生或者两者之前或同时与克()相关的两个序列点后。你能不能告诉是命令序列点将发生在 - 的f点是否对G点之前发生,反之亦然。

The expression f() + g() contains a minimum of 4 sequence points; one before the call to f() (after all zero of its arguments are evaluated); one before the call to g() (after all zero of its arguments are evaluated); one as the call to f() returns; and one as the call to g() returns. Further, the two sequence points associated with f() occur either both before or both after the two sequence points associated with g(). What you cannot tell is which order the sequence points will occur in - whether the f-points occur before the g-points or vice versa.

即使编译器内联code,它必须服从,如果规则 - 在code必须具有相同的行为,如果功能不交错。这限制了损害范围(假设非越野车编译器)。

Even if the compiler inlined the code, it has to obey the 'as if' rule - the code must behave the same as if the functions were not interleaved. That limits the scope for damage (assuming a non-buggy compiler).

所以这个顺序在 F()克()评估是不确定的。但一切是pretty干净。

So the sequence in which f() and g() are evaluated is unspecified. But everything else is pretty clean.

在一个评论, supercat 问:

我希望在源$ C ​​$ C函数调用继续作为序列指出,即使一个编译器决定自身的内联它们。是否仍然存在的功能真正宣布内联,还是编译器获得额外的纬度?

I would expect function calls in the source code remain as sequence points even if a compiler decides on its own to inline them. Does that remain true of functions declared "inline", or does the compiler get extra latitude?

我相信,'仿佛'规则适用和编译器不会获得额外的纬度省略序列点,因为它使用一个明确的在线功能。对于认为(是懒得看在标准的确切写法)主要的原因是编译器允许内联或不内联根据其规则的功能,但是程序的行为不应该改变(除性能)。

I believe the 'as if' rule applies and the compiler doesn't get extra latitude to omit sequence points because it uses an explicitly inline function. The main reason for thinking that (being too lazy to look for the exact wording in the standard) is that the compiler is allowed to inline or not inline a function according to its rules, but the behaviour of the program should not change (except for performance).

此外,什么可以说关于的顺序(A(),B())+(C(),D())?是否有可能为 C()和/或 D() 之间执行( ) b(),或 A() b()之间的 C到的execute() D()

Also, what can be said about the sequencing of (a(),b()) + (c(),d())? Is it possible for c() and/or d() to execute between a() and b(), or for a() or b() to execute between c() and d()?


  • 显然,B之前A执行,而C D之前执行。我相信这是可能的c和d a和b之间被执行,虽然这是相当不可能的,它的编译器会生成code那样;同样地,a和b可以c和d之间执行。并且虽然我在'c和d'用和,这可能是一个或 - 即,任何操作的这些序列的满足约束:

  • Clearly, a executes before b, and c executes before d. I believe it is possible for c and d to be executed between a and b, though it is fairly unlikely that it the compiler would generate the code like that; similarly, a and b could be executed between c and d. And although I used 'and' in 'c and d', that could be an 'or' - that is, any of these sequences of operation meet the constraints:


    • ABCD

    • ACBD

    • ACDB

    • 农发行

    • CDAB

    • CABD

    我不能肯定这是一个详尽列表,但它涵盖了大部分的变种。

    I'm not certain that's an exhaustive listing, but it covers most of the variants.

    如果这样的事情是可能的,这将意味着内联函数和宏之间的差异显著。

    If such a thing would be possible, that would imply a significant difference between inline functions and macros.

    有内联函数和宏之间显著差异,但我不认为在EX pression排序就是其中之一。也就是说,任何功能的a,b,c或d可能与宏代替,并且可能发生宏观体的相同排序。主要的区别,在我看来,是与内联函数,还有在函数调用序列保证点 - 在逗号运营商以及 - 在主要答复概述。用宏,你失去了功能相关序列点。 (所以,也许这是一个显著区别...)但是,在很多方面的问题,而不是像有关在销的头部有多少天使能跳舞的问题 - 这是不是在实践中非常重要。如果有人presented我与前pression (A(),B())+(C(),D())在code检讨,我会告诉他们重写code要清楚:

    There are significant differences between inline functions and macros, but I don't think the ordering in the expression is one of them. That is, any of the functions a, b, c or d could be replaced with a macro, and the same sequencing of the macro bodies could occur. The primary difference, it seems to me, is that with the inline functions, there are guaranteed sequence points at the function calls - as outlined in the main answer - as well as at the comma operators. With macros, you lose the function-related sequence points. (So, maybe that is a significant difference...) However, in so many ways the issue is rather like questions about how many angels can dance on the head of a pin - it isn't very important in practice. If someone presented me with the expression (a(),b()) + (c(),d()) in a code review, I would tell them to rewrite the code to make it clear:

    a();
    c();
    x = b() + d();
    

    和假定上有 B没有关键时序要求() VS D()

    这篇关于在C99,为f()+ G()未定义或仅仅是不确定的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆