gpt4 book ai didi

c - 第 5.1.2.3 节第 4 段(在 n1570.pdf 中)对空操作意味着什么?

转载 作者:太空狗 更新时间:2023-10-29 17:03:09 26 4
gpt4 key购买 nike

我多次被告知不能优化访问 volatile 对象,但在我看来,C89、C99 和 C11 标准中的本节另有建议:

... An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

如果我没理解错的话,这句话是在说明实际实现可以优化表达式的一部分,前提是满足以下两个要求:

  • “它的值(value)没有被使用”,并且
  • “没有产生任何必要的副作用(包括任何由调用函数或访问 volatile 对象引起的副作用)”...

在我看来,很多人混淆了“包括”和“排除”的含义。

编译器是否可以区分“需要”和“不需要”的副作用?如果计时被认为是必要的副作用,那么为什么允许编译器优化空操作,如 do_nothing();int unused_variable = 0;

如果编译器能够推断出函数什么都不做(例如 void do_nothing() { }),那么编译器是否有理由优化对该函数的调用?

如果编译器能够推断出 volatile 对象没有映射到任何重要的东西(即它可能映射到 /dev/null 以形成空操作),那么编译器是否也有理由优化这种非关键的副作用?

如果编译器可以执行优化以消除不必要的代码,例如在称为“死代码消除”(这是很常见的做法)的过程中调用 do_nothing(),那么为什么不能编译器还消除了对空设备的 volatile 写入?

据我了解,由于 5.1.2.3p4,编译器可以优化掉对函数或 volatile 访问的调用,或者编译器不能优化掉。

最佳答案

我认为“包括任何”适用于“需要的副作用”,而您似乎将其解读为适用于“表达式的一部分”。

所以本意是说:

... An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced .

Examples of needed side-effects include:

  • Needed side-effects caused by a function which this expression calls
  • Accesses to volatile variables

现在,术语需要的副作用 没有由标准定义。第/4 节也没有尝试对其进行定义——它正在尝试(但不太成功)提供示例。

我认为唯一明智的解释是将其视为 5.1.2.3/6 定义的可观察行为。所以写起来会简单得多:

An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no observable behaviour would be caused.


您在编辑中的问题由 5.1.2.3/6 回答,有时称为假设规则,我将在此处引用:

The least requirements on a conforming implementation are:

  • Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.
  • At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.
  • The input and output dynamics of interactive devices shall take place as specified in 7.21.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.

This is the observable behaviour of the program.

回答编辑中的具体问题:

Is it possible for a compiler to distinguish between a side effect that's "needed", and a side effect that isn't? If timing is considered a needed side effect, then why are compilers allowed to optimise away null operations like do_nothing(); or int unused_variable = 0;?

时机不是副作用。 “需要的”副作用在这里大概是指导致可观察到的行为的副作用。

If a compiler is able to deduce that a function does nothing (eg. void do_nothing() { }), then is it possible that the compiler might have justification to optimise calls to that function away?

是的,这些可以被优化掉,因为它们不会导致可观察到的行为。

If a compiler is able to deduce that a volatile object isn't mapped to anything crucial (i.e. perhaps it's mapped to /dev/null to form a null operation), then is it possible that the compiler might also have justification to optimise that non-crucial side-effect away?

不,因为对 volatile 对象的访问被定义为可观察的行为。

If a compiler can perform optimisations to eliminate unnecessary code such as calls to do_nothing() in a process called "dead code elimination" (which is quite the common practice), then why can't the compiler also eliminate volatile writes to a null device?

因为 volatile 访问被定义为可观察的行为,而空函数则不是。

关于c - 第 5.1.2.3 节第 4 段(在 n1570.pdf 中)对空操作意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30472968/

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