![](/img/trans.png)
[英]Pass const data to function taking non-const without const_cast
[英]Is it safe to remove const via const_cast and invoke a non-const function that does not modify the resulting object?
我知道應該小心地拋棄const
-ness,並且任何從初始const
對象中刪除const
-ness然后修改對象的嘗試都會導致未定義的行為。 如果我們想刪除const
-ness以便我們可以調用一個不修改對象的非const函數,該怎么辦? 我知道我們實際上應該標記這樣的函數const
,但是假設我使用的是一個沒有const
版本的“壞”代碼。
那么,總結一下,下面的代碼是“安全的”嗎? 我的猜測是,只要你沒有最終修改對象你就可以了,但我不是百分百肯定。
#include <iostream>
struct Foo
{
void f() // doesn't modify the instance, although is not marked const
{
std::cout << "Foo::f()" << std::endl;
}
};
int main()
{
const Foo foo;
const_cast<Foo&>(foo).f(); // is this safe?
}
這個特定的例子恰好是安全的(具有良好定義的行為),因為沒有寫入聲明為const
的對象。
我們在[dcl.type.cv]中有這個:
除了可以修改聲明為
mutable
(7.1.1)的任何類成員之外,任何在其生命周期內修改const
對象的嘗試(3.8)都會導致未定義的行為。
[expr.const.cast]中有一條注釋(非規范性),其中說明:
[注意:根據對象的類型,通過指針,左值或指向數據成員的指針的寫入操作會導致const-qualifier的
const_cast
產生未定義的行為(7.1.6.1)。 - 尾注]
嘗試在const_cast
[可能]導致未定義的行為后修改對象或寫入操作。 在這里,我們沒有寫操作。
關於const_cast
未定義行為由C ++ 11標准的§3.8/ 9定義 (§3.8是“對象生存期”):
”在創建一個存儲位置的新對象
const
靜態,螺紋,或自動存儲持續時間對象占用或者,在這樣的存儲位置const
用來占據其生命周期結束導致不確定的行為之前的對象。
和§7.1.6.1/ 4 (§7.1.6.1是“ cv-qualifiers ”)
“除了可以修改任何聲明為
mutable
類成員(7.1.1)之外,任何在其生命周期內修改const
對象的嘗試(3.8)都會導致未定義的行為。
換句話說,如果修改原始const
對象,則獲得UB,否則為1 。
const_cast
本身不會引入UB。
在§5.2.11/ 7中還有一個非規范性的注釋,“取決於類型”,通過從const_cast
獲得的指針或引用進行寫入,可能具有未定義的行為。
這種非規范的音符是如此毛茸茸的,它有它自己的非規范性的注腳,那解釋說:“ const_cast
不限於拋棄一個轉換const
-qualifier。”
然而,仍然有了這個澄清,我沒有想到任何情況下寫入可以明確定義或不取決於類型,即,我沒有理解這個說明。 這里的另外兩個答案集中在本說明中的“寫”一詞,並且必須通過§3.8/ 9進入UB-land,是的。 對我來說相當可疑的方面是“取決於類型”,這似乎是該注釋的重要部分。
1)除非關於其他非const_cast
相關事物的UB規則發揮作用,例如使以后在除了作為typeid
-exression之外的上下文中解除引用的指針歸零。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.