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