簡體   English   中英

const_cast和UB

[英]const_cast and UB

$ 5.2.11 / 7 - “[注意:根據對象的類型,通過指針,左值或指向數據成員的指針進行寫入操作會導致const-qualifier68的const_cast) 可能會產生未定義的行為(7.1。 5.1)。]“

本節的措辭(C ++ 03)對我來說是令人驚訝的。 令人驚訝的是兩件事。

a)首先,使用'可能'。 為什么'可能'? 標准中的其他地方對未定義的行為非常明確

b)為什么拋棄原始const對象的常量而不是直接'未定義的行為'。 為什么要觸發UB需要寫入?

a)首先,使用'可能'。 為什么'可能'? 標准中的其他地方對未定義的行為非常明確

不要太深入地使用這個詞這里可以的。 關鍵是,在這種情況下拋棄constness會導致未定義的行為。

C ++標准經常使用“可能”或“可能”,如:

1.3.12:當本國際標准忽略了行為的任何明確定義的描述也可以預期不確定的行為。

強調我的。 基本上,標准使用“可以”一詞,如“ 允許 ”。

b)為什么拋棄原始const對象的常量而不是直接'未定義的行為'。 為什么要觸發UB需要寫入?

寫入觸發UB,因為const對象可能存儲在某些平台上的只讀內存中。

我的理解是,如果所討論的對象基本上是一個const對象而不是一個const指針或對一個最初不是const的對象的引用,它將只是UB。

這個想法是基本上是const的數據可以加載到內存的只讀部分,而寫入它只是不起作用。 但是,如果有問題的對象基本上是可變的,那么它可以保證正常工作。

例如:

const int  x = 4;
const int *y = x;

*const_cast<int*>(x) = 3; // UB - the pointed-to object may 
                          // be in read-only memory or whatever.

int        a = 7;
const int *b = a;

*const_cast<int*>(b) = 6; // Not UB - the pointed-to object is 
                          // fundamentally mutable.

對於下面的評論,因為代碼在評論中看起來很糟糕:

在標准的§7.1.5.1/ 4中,給出的例子是:

int i = 2;
const int * cip; // pointer to const int
cip = &i;        // OK: cv-qualified access path to unqualified
...
int* ip;
ip = const_cast <int *>( cip ); // cast needed to convert const int* to int*
*ip = 4;                        // defined: *ip points to i, a non-const object

所以這是特別允許的。

對於你的第一個問題,如果某些東西可能會產生未定義的行為,那么這不會使它變得不那么明確。

對於第二部分,我認為這是出於互操作性的原因。 例如,C不會(或者在C99之前沒有)具有const關鍵字,因此如果要將const對象傳遞給C函數,則必須拋棄const。 所以C ++標准規定只要不執行寫操作就允許這樣做。 如果C函數是只讀的,則可以安全地丟棄常量。

即使在C ++中,不一致或不完整的const正確性也很常見。 所以我們偶爾會遇到這樣的情況:為了將一個const對象傳遞給一個不修改其參數的函數,而是將它傳遞給非const,我們必須拋棄const。

我相信這是因為const對象可以存儲到只讀內存中。 因此,寫入它可能會產生許多不同的影響:程序崩潰,分段錯誤或無效。

暫無
暫無

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

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