English 中文(简体)
C++空闲,而循环优化则与循环状态中使用的全球变量和当地变量不同。
原标题:C++ empty while loop optimization behaves differently with global vs local variable used in loop condition [duplicate]
  • 时间:2024-02-10 22:54:39
  •  标签:
  • c++

The code in this post is an example from CppCon2023 - Fedor Pikus s talk on UB. Unfortunately, the speaker does not explain this specific behavior in their talk - this knowledge is presumed to be common among the attendees, but I am sadly missing it...

The following Code, prepared with -O3 using both Corng or gcc (various texts Trial in Compiler Exploration), shows different conduct if int i is global vs local to main。 具体来说,如果<代码>t i是全球性的,那么空洞就消失了,但如果是地方性的的话。

#include <iostream>

int i = 1;
int main() {
    std::cout << "Before infinite loop" << std::endl;
    while (i) {}
    std::cout << "After infinite loop.... wat?" << std::endl;
}

我以上述话题和在StackOverflow上的类似问题为基础,理解空档为UB,可以由汇编者去除;我不理解(而且不能发现任何关于这一主题的信息)

在界定了<代码>int i的情况下,为何如此?

最佳回答

行为因一号内的范围而有所不同的原因

该方案本身在这两种情况下都没有界定行为,因为没有原子/挥发性/IO/同步化作业的无限循环。 因此,无论在何种范围内,消除 lo、保持 lo或做任何其他事情都是有效的。


一些关于全球范围缺乏优化的争论:

在汇编<代码>main功能时,至少假设LTO isn t使用,但汇编者不知道这是整个方案。 可能还有其他翻译单位。

这样一个单位可以这样做:

extern int i;
int j = (i=0);

由于i 具有不断的初始化,在j 启动之前保证进行初步化,如果实施在main之前作出动态初步确定选择,则该格式的<代码>i所产生的数值为0,而不是

因此,即使初始编制者在同一个翻译单位看到,汇编者也可以对<代码>main中全球变量的价值作出假设。

除此以外,汇编者没有足够信息来知道, lo之前的产出线并没有改变全球。 但是,由于上述原因,如果没有诊断结果,我并不期望结果会改变。

因此,汇编者可能会将<代码>i视为在册体内价值不明。 因此,也许最优化的缺点是,不承认消除这一漏洞在所有情况下都是正确的: <i> ,<0>>0 , lo 绝未入, 或该 lo已定并具有UB。


我似乎误解了这一点。 如果在全球范围实现最佳化,那么最优化者可能就足够了,以承认我上文所述的可能结果。

如果在产出说明之前写出<代码>i的价值,则当地范围缺失的优化可能是同样的原因。

然而,特别是如果它被立即置于 lo之前,那么,我预计,不搬迁 lo会是编辑作者蓄意选择的。

许多C++(和C)用户认为,他们可以使用像这种无限的 lo,无限期地等待。 在C区,如果居住条件是整体不变的,甚至有可能发生这种情况(在你看来并非如此)。 但C++甚至不允许这样做。 因此,我确信,它们至少有意不优化表格的样子:<代码>while (1);。 无论你的形式是故意不优化的,还是由于持续推行这种形式。

问题回答

请注意,对<代码>i的界定并不相干。 值得注意的是,对不明确行为进行解释,就像阅读茶叶或晶体 g或说白白。 您的问题是:

因此,[实际产生]行为因一号内的范围而有所不同。

由于海合会无法证明,在航程之前不会改变<代码>i,而且你没有使用LTO或全程优化。 审议<编码>edit.cpp:

extern int i;
struct Edit {
    Edit() {
        i = 0;
    }
};
Edit edit{};

汇编:

g++ -c main.cpp
g++ -c edit.cpp
g++ main.o edit.o

不可能在<代码>g++-c main.cpp上知道该休息室将执行或不执行,因此无法优化。 相比之下:

g++ -O2 -fwhole-program main.cpp

由于<代码>g++>知道这是整个方案,因此将优化休息时间。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?