如果编译器可以证明一个类的(私有)成员从未被使用过,包括潜在的朋友,标准是否允许编译器从类的内存占用中删除这个成员?
不言而喻,这对于受保护或公共成员在编译时是不可能的,但在某些情况下,私有数据成员可能会构造这样的证明。
相关问题:
为什么这种未定义的行为?
struct s
{
const int id; // <-- const member
s(int id):
id(id)
{}
s& operator =(const s& m) {
return *new(this) s(m); // <-- undefined behavior?
}
};
Run Code Online (Sandbox Code Playgroud)
(从标准引用会很好).
这个问题来自于这个答案.
我已经在 Google 和 Stack Overflow 上搜索了一些答案,并且我知道编译器不能假设函数不会修改通过 const 引用传递的参数,因为这些函数可能会通过const_cast. 但是,当原始对象本身定义为 时,这样做是未定义的行为const。来自cpreference
通过非常量访问路径修改常量对象并通过非易失性左值引用易失性对象会导致未定义的行为。
对于以下代码
void fun(const int&);
int f1() {
const int i = 3;
fun(i);
return i;
}
static int bar(const int i) {
fun(i);
return i;
}
int f2() {
return bar(3);
}
Run Code Online (Sandbox Code Playgroud)
GCC 和 Clang 都能够优化函数f1()以直接返回3,因为编译器认为调用fun(i)不会修改 的值i,因为这样的操作会导致未定义的行为。然而,GCC 和 Clang 都无法对该函数应用相同的优化f2()。编译器仍然生成代码以从内存加载值i。f1()下面是 GCC生成的代码f2()。编译器资源管理器
f1():
subq $24, %rsp
leaq 12(%rsp), …Run Code Online (Sandbox Code Playgroud)