簡體   English   中英

通過const_cast刪除const並調用不修改結果對象的非const函數是否安全?

[英]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-qualifierconst_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.

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