在问题中:假设我有一小段这样的代码:
#include <iostream>
using namespace std;
struct foo {
int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用g++ -g -O2
它编译结果证明,x
初始化是最优化的.
然而那个:
#include <iostream>
using namespace std;
struct foo {
volatile int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
调用构造函数.
如果我尝试使用代码中的变量,(即cout << foo.a << endl;
),在两种情况下,程序集输出都是等效的.
我是否得到以下权利:
在第一种情况下,根本无法访问结构,因此它完全被优化掉了.
在第二个中,struct的字段被指示为在构造期间也可以改变的字段,因此无论如何都调用foo().
补充:我试图摆弄上面的代码:调用类似于while(foo.a--);
预期的工作,它实际上发生而不是在优化期间被结果删除/替换,因此似乎volatile实际上是继承的,但ctor在这种奇怪的行为(至少或至少意外的方式.
编辑2:
我用clang和MSVC检查它,它的行为与gcc相同.
最近,我编写了一些实验代码,为所有没有运算符的类添加运算符>。代码在这里:
#include <cstdio>
#include <experimental/type_traits>
#include <type_traits>
struct A {
A(int x) : x(x) {}
int x;
bool operator<(const A &rhs) const {
printf("original lt\n");
return x < rhs.x;
}
};
template <class T> using gt_t = decltype(std::declval<T>() > std::declval<T>());
template <class Key>
std::enable_if_t<!std::experimental::is_detected<gt_t, Key>::value, bool>
operator>(const Key &lhs, const Key &rhs) {
printf("generated gt\n");
return rhs < lhs;
}
int main() {
A a(1);
A b(2);
printf("%d\n", b > a);
}
Run Code Online (Sandbox Code Playgroud)
我使用“-O2 -std=c++14”进行编译,gcc 8.1及更高版本编译成功,而gcc 7.5及更早版本生成编译错误(godbolt链接),例如
<source>: In …
Run Code Online (Sandbox Code Playgroud)