可变成员是否对非可变成员禁用const优化?

Mir*_*pas 5 c++ const mutable

据我所知,在C++中,具有相同访问控制的类/成员以声明顺序存储在内存中.是下一个例子m,c应该一个接一个地存储:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

这让我很奇怪 - 一个mutable成员是否禁用const整个优化struct(以某种方式使所有成员mutable)?

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

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

Pie*_*aud 5

该标准涉及mutable许多地方的成员.我在下面引用标准的三个部分,解释说你只能修改mutable一个const对象的成员.否则它是未定义的行为.

3.9.3 CV限定符[basic.type.qualifier]

const对象是类型的对象const T或这样的对象的非易变的子对象.

[...]

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

mutable一类数据成员指定符勾销施加到含有类对象一个const说明符,并且允许的修改mutable类成员,即使对象的其余部分是const.

[...]

7.1.6.1 cv限定符[dcl.type.cv]

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


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

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


Mat*_*son 4

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

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

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