5

据我所知,在 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成员是否会禁用const整个优化struct(不知何故让所有成员mutable)?

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

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

4

3 回答 3

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)期间修改对象的尝试都会导致未定义的行为


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

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

于 2013-09-03T07:41:10.063 回答
4

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

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

此外,如果您向您struct的 .

于 2013-09-03T09:00:59.510 回答
1

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

于 2013-09-03T07:22:02.023 回答