可变成员是否禁用不可变成员的常量优化

Does mutable member disable const optimizations for non-mutable members?

本文关键字:成员 常量 不可变 优化 是否      更新时间:2023-10-16

我所知C++具有相同访问控制的结构/类成员按声明顺序存储在内存中。是下一个示例mc应该一个接一个地存储:

#include <cstdlib>
#include <iostream>
struct X
{
    mutable int m;
    int         c;
};
const X cx = {0, 1};
int main()
{   
    X& x = const_cast<X&>(cx);
    x.m = rand();
    x.c = rand();
    std::cout<<x.m<<" "<<x.c;
}

在此示例中,程序运行并打印 2 个随机数。如果我删除mutable它会崩溃cx因为它存储在只读受保护的内存中。

这让我想知道 - 一个mutable成员是否禁用了整个structconst优化(以某种方式使所有成员都mutable(?

是否可以将struct的一部分存储在只读内存中,而将其他部分存储在非只读内存中并遵守标准内存布局C++?

这是在Windows 7上使用Visual Studio 2010和Ubuntu上的GCC 4.7.2进行测试的。

该标准在许多地方谈论mutable成员。我在下面引用标准的三个部分,解释您只能修改const对象的mutable成员。否则就是未定义的行为

3.9.3 CV限定符[基本类型限定符]

const 对象是类型为 const T 的对象或此类对象的不可变子对象。

[...]

7.1.1 存储类说明符 [dcl.stc]

类数据成员上的mutable说明符使应用于包含类对象的 const 说明符无效,并允许修改mutable类成员,即使对象的其余部分const

[...]

7.1.6.1 简历限定词 [dcl.type.cv]

除了可以修改声明mutable (7.1.1( 的任何类成员之外,任何在 const 对象的生存期 (3.8( 期间修改其尝试都会导致未定义的行为

<小时 />

是否可以将struct的一部分存储在只读内存中,而将其他部分存储在非只读内存中并遵守标准内存布局C++?

不,不可能将struct(或class(的一部分存储在与对象其余部分不同的内存区域中。

解释为什么编译器在存储struct的位置时必须"全有或全无":在大多数处理器中,内存页为 4KB(少数有 8KB 页(。这就是"只读"与"读/写"内存块的粒度。因此,您不能在只读内存中有一个 4 字节整数,然后在读写内存中有一个下一个 4 字节整数(除非它们完全跨越 4KB 内存边界 - 但如果你有一个包含 3000 个内存的数组,占用 12MB,这肯定会浪费内存(。

请注意,这不是"优化"。只读存储器并不比读写存储器快。这是一种保护,防止用户愚蠢地使用const并写入他们不应该写入的数据。

此外,如果您添加一个对struct"做某事"的构造函数,它很可能会将结构存储在读写内存中,因为编译器生成代码以在运行时打开和关闭只读非常棘手。

关键字"const"更像是程序员团队的标签,如"private"和"public",而不是编译器指令或编译器提示。编译器可以使用它来进行优化,但不需要这样做。编译器只需要控制滥用并防止滥用。所以你看到的行为是完全可以的。不,一个结构实例或类实例的某些部分不可能存在于不同的内存区域中(不计算映射(。因为该决定会影响结构的使用,并且必须得到程序员的允许。