簡體   English   中英

使用沒有顯式強制轉換的常量調用未定義行為?

[英]is using a constant without an explicit cast invoke undefined behavior?

在調用一個函數或從一個函數返回一個期望值為T類型的值的值時,是否使用不帶顯式強制轉換的常量文字調用未定義的行為?

例如,我們有一個函數的原型是long foo(unsigned long x); 調用: foo(4); //does this invoke UB? foo(4); //does this invoke UB?

long foo(unsigned long x) { x += 10; return 10; } // does this invoke UB ?

我們應該寫foo((unsigned long)4)return (long)10嗎?

不,這都是定義明確的。

兩種類型之間存在一個隱式轉換規則,因此int會簡單地轉換為unsigned long ,並且程序會按預期運行。

文字4類型為int (在C節6.4.4.1整數常量中,類似的節在C ++中也可用)

在C和C ++中都很好地定義了從intunsigned long隱式轉換。 (在C第6.3.3.1節中)

我們應該寫foo((unsigned long)4)並返回(long)10嗎?

您的兩個示例均定義良好,因此盡管可以接受這種轉換是多余的。

考慮下面的C代碼:

// foo.c
int foo(unsigned long x) { }

// main.c
int foo();

int main()
{
     foo(4);    // UB
     foo((unsigned long)4);   // OK
}

foo(4)調用是UB,因為在調用范圍內沒有原型的函數時,必須手動確保參數匹配。 默認參數提升出現,僅此而已。

當然,從編寫健壯的代碼的角度來看,編寫強制轉換是一個不好的解決方案。 更好的解決方案是編寫一個原型:

int foo(unsigned long);

包含在兩個.c文件中的頭文件中。


return 10; case永遠不能是UB,因為編譯器在編譯函數體內的代碼時會知道函數的真實返回類型。

不,這沒有意義,因為這樣的參數在C和C ++中都是通過值傳遞

long foo(unsigned long x);

您可能認為它是技術上的,因為x參數是在foo內部定義的本地自動變量,並分配有傳遞參數的值:

unsigned long x = 4;

如果參數的類型與參數不匹配,則編譯器將嘗試進行隱式轉換。 例如,將double類型的參數靜默轉換為unsigned long類型,即使這意味着信息丟失(盡管您可能會收到編譯器警告)。

但是,當您將x參數的類型標記為引用時,可能會遇到麻煩(僅C ++):

long foo(unsigned long& x);

在這里,編譯器不允許您將其稱為foo(4) ,因為您現在通過引用傳遞,並且不能這樣修改4 但是,如果參數用const限定符標記,則可以傳遞它:

long foo(const unsigned long& x);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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