在 C 中,可以透過空指標存取類別的靜態成員,而不會呼叫未定義的行為。這種行為可能看起來令人驚訝,但可以透過檢查語言的定義和基本原理來解釋。
透過空指標存取類別成員時,該行為很好 -只要操作數的計算不需要指示物件的身份或儲存值即可定義。例如,存取靜態成員變數 d->a 只是計算表達式 *(d) 以獲得物件的引用,但不執行需要初始化引用物件的操作。
此計算該過程由 [expr.ref]/2 支持,其中指出 d->a 轉換為 ((d)).a。由 *d 表示的 ((d)) 的計算繼續進行,不會觸發任何錯誤,因為不需要 d 引用的物件。
C 標準沒有明確聲明透過空指標的間接尋址本質上會導致未定義的行為。事實上,CWG 問題 #232 和 #315 表明,單純的間接尋址並沒有問題。
這一立場的主要論點在於存在明確定義的場景,其中允許透過空指標進行間接尋址。例如,[expr.typeid]/2 允許 typeid(*((A*)0)) 拋出 bad_typeid 異常,即使 *d 計算結果為 null。如果只是間接呼叫 UB,則該語句不會被明確定義。
在您的範例中,
<code class="cpp">int main() { demo* d = nullptr; d->fun(); std::cout << d->a; return 0; }</code>
程式編譯並執行時間沒有錯誤是因為呼叫靜態成員函數或存取靜態變數不需要指示對象的標識。因此,您的程式不存在任何固有問題或未定義的行為。
以上是您可以在沒有未定義行為的情況下使用空指標存取 C 中的靜態成員嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!