首頁 > 後端開發 > C++ > 為什麼在 C 中允許使用空指標存取靜態成員?

為什麼在 C 中允許使用空指標存取靜態成員?

Susan Sarandon
發布: 2024-11-03 01:33:02
原創
942 人瀏覽過

Why is it allowed to access static members using a null pointer in C  ?

在C 中使用空指標存取靜態成員

上下文

考慮以下程式:

<code class="cpp">#include <iostream>
class Demo
{
public:
    static void func() { std::cout << "func() called" << std::endl; }
    static int num = 9;
};

int main()
{
    Demo* d = nullptr;
    d->func();
    std::cout << d->num << std::endl;
    return 0;
}</code>
登入後複製

問題

問題

程式編譯並執行沒有錯誤,而透過空指標存取靜態成員通常被認為是未定義的行為。為什麼允許這樣做?

答案

TL;DR:

給定的程式不會觸發未定義的行為,因為透過空指標的間接定址不是本質上是有問題的,除非它涉及依賴有效物件標識的進一步操作。

解釋:

透過空指標的間接是否本質上是未定義的行為一直是個爭論的問題。程式中唯一有問題的操作是表達式 d->a 的計算。由於指標解引用規則,

d->a 等效於 (*d).a。然而,即使 *d 未定義,表達式 *d 仍會被求值,特別是當其結果被丟棄時,如 d->a 的情況。這種行為是明確定義的。

靜態成員的行為與透過空指標存取非靜態成員不同,後者確實應該觸發未定義的行為,因為它意味著無效的物件標識。相反,存取靜態成員不需要物件標識,並且它們的行為在標準中明確定義。

其他注意事項

  • CWG 問題#232 強調了處理之間的差異在C 標準中透過空指針間接調用,表明它本身可能不會導致未定義的行為。
  • CWG 問題 #315 專門解決了透過空指標呼叫成員函數的場景,重申間接本身是除非涉及依賴於物件標識的進一步操作,否則不是錯誤。
  • 丟棄表達式結果(丟棄值表達式)的處理方式與存取值不同,這可能會根據上下文觸發錯誤。

結論

給定的程式不會造成任何危害,因為在存取靜態成員的上下文中允許對 *d 進行求值。僅透過空指標間接不一定會導致未定義的行為,但重要的是要意識到與需要物件識別的進一步操作相關的潛在風險。

以上是為什麼在 C 中允許使用空指標存取靜態成員?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板