考慮以下程式:
<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 的情況。這種行為是明確定義的。
靜態成員的行為與透過空指標存取非靜態成員不同,後者確實應該觸發未定義的行為,因為它意味著無效的物件標識。相反,存取靜態成員不需要物件標識,並且它們的行為在標準中明確定義。
給定的程式不會造成任何危害,因為在存取靜態成員的上下文中允許對 *d 進行求值。僅透過空指標間接不一定會導致未定義的行為,但重要的是要意識到與需要物件識別的進一步操作相關的潛在風險。
以上是為什麼在 C 中允許使用空指標存取靜態成員?的詳細內容。更多資訊請關注PHP中文網其他相關文章!