C++ 作用域与编译器优化的相关性

C++ 作用域与编译器优化的相关性,c++,scope,compiler-optimization,C++,Scope,Compiler Optimization,我有一个,它在编译时进行重循环展开。我还使用了一个基准点工具,它通过在一个范围内实例化一个结构来工作,在销毁时,它测量创建和销毁之间的时间,并返回收集到的值。现在,通过在其中插入一些函数调用,它可以测量函数调用的时间。我想知道的是,编译器能跳转作用域吗?(参见下面的代码) 或者换句话说:编译器是否可以将工作“外包”到范围之外(我得到了奇怪的结果,我想知道)只要代码的可观察结果(按照标准的定义)是相同的——在优化之前和之后,编译器可以做任何它想要的转换 注:例如,执行速度不被视为可观察的结果。此外

我有一个,它在编译时进行重循环展开。我还使用了一个基准点工具,它通过在一个范围内实例化一个结构来工作,在销毁时,它测量创建和销毁之间的时间,并返回收集到的值。现在,通过在其中插入一些函数调用,它可以测量函数调用的时间。我想知道的是,编译器能跳转作用域吗?(参见下面的代码)


或者换句话说:编译器是否可以将工作“外包”到范围之外(我得到了奇怪的结果,我想知道)

只要代码的可观察结果(按照标准的定义)是相同的——在优化之前和之后,编译器可以做任何它想要的转换


注:例如,执行速度不被视为可观察的结果。此外,如果您的程序包含未定义的行为,则任何结果都是可接受的。

如果您的
PerfEventBlock
构造函数和析构函数执行系统调用,则编译器应无法证明它没有可观察到的副作用。然而,它仍然可以(理论上)在这些之前或之后重新排序您的间歇代码,只要它能够证明这样做不会从抽象机器的角度改变可观察的行为。另见,例如

例如:

void inc(int& a) { ++a; }

void foo();

int bar()
{
    int a = 1;
    foo();
    inc(a);
    foo();
    return a;
}

编译器不知道
foo()
做了什么,因此它必须假设存在可观察到的副作用。不过,您可以在程序集中看到,
inc
非常简单,编译器将其内联(并将常量折叠)在一起。在两个副作用之间,没有义务执行
inc(a)
所涉及的任何操作,因为
inc
本身没有外部可观察的影响


因此,编译器可能会在
PerfEventBlock
的构造函数和析构函数之间移动要分析的代码。事实上,通过链接时间优化,此选项可以保留在表中的位置比您想象的要远(对另一个编译单元的函数调用,例如
foo()
,可能对编译器而不是链接器来说是不透明的)。

您能澄清一下您的意思吗,告诉我们a到底出了什么问题。如果你得到了奇怪的结果,你应该发布a,我们可以告诉你原因。以这种形式问他们的问题太广泛了,你会得到像下面这样的一般性答案。为什么不看看生成的代码?@CleboSevic你太个人化了。除了你确实收到了关于如何改进你的问题的评论外,downvote按钮本身表示它适用于不清楚的问题。我不能否认这一点,虽然我有点明白你想要什么(这就是为什么我没有被否决的原因),但这只是含糊不清的措辞。“外包”和“跳转作用域”没有特别的含义,而您的意思可能是“在作用域之外运行构造函数/析构函数”。值得澄清的是,执行速度不被视为可观察的结果。但也值得注意的是,对任何类型的计时工具的调用通常对编译器来说都是不透明的,因此无法证明它没有副作用。因此,编译器不能随意重新排序计时调用。@MaxLanghof如果你是正确的,但是如果我要列出所有不被认为是可观察的副作用的东西,那么我最好引用标准。列出所有对编译器不透明的内容也将是一个冗长的列表。我相信我已经在当前问题中提到了与OP相关的所有内容。所以我就到此为止。
void inc(int& a) { ++a; }

void foo();

int bar()
{
    int a = 1;
    foo();
    inc(a);
    foo();
    return a;
}