簡體   English   中英

可變成員是否對非可變成員禁用const優化?

[英]Does mutable member disable const optimizations for non-mutable members?

據我所知,在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成員是否禁用整個struct const優化(以某種方式使所有成員都可mutable )?

是否可以將struct的一部分存儲在只讀存儲器中,而將其他部分存儲在非只讀存儲器中並遵守C ++標准存儲器布局?

這是在Windows 7上使用Visual Studio 2010和在Ubuntu上使用GCC 4.7.2測試的。

該標准涉及許多地方的mutable成員。 我在下面引用標准的三個部分,解釋說你只能修改const對象的mutable成員。 否則它是未定義的行為

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 )的一部分存儲在與對象的其余部分不同的存儲區域中。

解釋為什么編譯器在存儲struct位置時必須“全有或全無”:在大多數處理器中,內存頁面是4KB(少數有8KB頁面)。 這是“只讀”與“讀/寫”內存塊的粒度。 所以你不能在只讀存儲器中有一個4字節的整數,然后讀寫存儲器中的下一個4字節整數(除非它們正好跨越4KB的存儲器邊界 - 但這肯定會造成非常浪費的使用內存,如果你有一個3000的數組,占用12MB)。

請注意,這不是“優化”。 只讀存儲器並不比讀寫存儲器快。 它可以防止用戶對const感到愚蠢,並且寫入他們不應該寫入的數據。

此外,如果您向結構添加“做某事”的構造struct ,它很可能將結構存儲在讀寫內存中,因為編譯器生成代碼以在運行時打開和關閉只讀是非常棘手的。

關鍵字“const”更像程序員團隊的標簽,如“private”和“public”,而不是編譯器指令或編譯器提示。 編譯器可以使用它進行優化,但不需要。 編譯器只需控制濫用並阻止它。 所以你看到的行為完全沒問題。 不,不可能一個結構實例或類實例的部分存在於不同的內存區域(不計入映射)。 因為該決定會影響結構的使用,並且程序員必須允許。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM