Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ -fno-elide构造函数是否包含在-O0或任何其他优化级别中?_C++_Gcc_Optimization_C++11 - Fatal编程技术网

C++ -fno-elide构造函数是否包含在-O0或任何其他优化级别中?

C++ -fno-elide构造函数是否包含在-O0或任何其他优化级别中?,c++,gcc,optimization,c++11,C++,Gcc,Optimization,C++11,-fno-elide构造函数是否包含在-O0或任何其他-O[其他级别]中 在我看来,-fno-elide构造函数是一个优化标志,-O是优化级别。因此,一些-O级别可能包括flag-fno-elide构造函数。 我说得对吗 换句话说,-fno-elide构造函数和-O..之间是否存在任何关系 换句话说,-fno-elide构造函数之间是否存在关系 还有-O 是的,这是一种关系,尽管很简单:除非您明确禁用它,否则gcc很可能会删除已经在-O0级别的构造函数。请参见底部的示例代码以获取证明 不过这很棘

-fno-elide构造函数是否包含在-O0或任何其他-O[其他级别]中

在我看来,-fno-elide构造函数是一个优化标志,-O是优化级别。因此,一些-O级别可能包括flag-fno-elide构造函数。 我说得对吗

换句话说,-fno-elide构造函数和-O..之间是否存在任何关系

换句话说,-fno-elide构造函数之间是否存在关系 还有-O

是的,这是一种关系,尽管很简单:除非您明确禁用它,否则gcc很可能会删除已经在
-O0
级别的构造函数。请参见底部的示例代码以获取证明

不过这很棘手,编译器可能会做非常糟糕的事情,请参阅。底线是:您始终需要检查生成的部件,以查看引擎盖下到底发生了什么

请记住(这是我能找到的与C++14最接近的近似值):

12.8/31当满足某些条件时,允许实现忽略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数有副作用。[……]


证明我声明的代码:

#include <cstdio>
constexpr int size = 1024;

struct A { int array[size] = { 0 }; };

int main() {
  A a = A();
  std::printf("%d\n", a.array[size-1]);
}
但是,使用
g++-std=c++11-Wall-O0-fno-elide构造函数-S elide.cpp
我得到:

    call    A::A()
    [...]
    call    A::A(A&&)

即使您使用
-O0
禁用优化,如果出于某种原因需要禁用elision,也必须另外禁用它。

我相信它可能是通过优化设置添加的,但是,我不确定是哪一个。关于:
因为有些编译器不会在允许的情况下执行复制省略,所以依赖复制/移动构造函数和析构函数的副作用的程序是不可移植的。
这不准确。该行为在标准(C++14 12.8/31和/32,甚至C++98 12.8/15)中有专门描述,因此它是“可移植的”。只是有些编译器会比其他编译器做更多的拷贝。类似“long”的位在某些平台上可以是32位,在其他平台上可以是64位。我的猜测是,如果你需要禁用RVO以确保你会有一些行为,你正在做一些可疑的事情。@paercebal谢谢,修复了!我猜写“可移植”的人的意思是,如果你切换到另一个编译器,那么奇怪的事情就会发生…:(是的,我完全同意,如果有人依赖这种行为是可疑的。无论如何,更新我的答案,谢谢!
    call    A::A()
    [...]
    call    A::A(A&&)