簡體   English   中英

為什么 clang 抱怨使用帶有“-std=c99”標志的可變長度 arrays?

[英]Why does clang complain about using variable-length arrays with '-std=c99' flag?

當我編譯這個實驗代碼時:

int main(void)
{
    int foo = 5;
    char bar[foo];
}

使用 clang 和'-Weverything'或單獨'-Wvla'標志與'-std=c99'標志相結合,我仍然收到警告:

警告:使用可變長度數組 [-Wvla]

這里的例子

盡管與后來的 C 標准(C11、C18 等)相比,符合 C99 的實現應該——其中 VLA 支持是可選的,支持可變長度 arrays,無一例外。


  • 為什么在 clang 中使用帶有'-std=c99'標志的 VLA 時仍會收到此警告?
  • 這是一個錯誤還是只是為了提示要注意遵守后來的 C 標准(以及 C89/C90)的實現?

您是正確的,符合 C99 的實現必須支持 VLA,而實現可以符合后來的 C 標准而不支持 VLA。 但我認為你只見樹木不見森林:我認為上述標准之間的差異正是警告的重點。 這並不是說您正在構建的代碼可能會出錯。 相反,它警告您依賴的功能不是普遍向前兼容的,因此如果您嘗試在其他地方構建代碼,它可能會崩潰。

如果 Clang 認為 VLA 是 C99 的非標准擴展,那么它根本不應該在-std=c99模式下接受您使用 VLA 的代碼。

人們可能希望避免在程序中使用可變長度 arrays 的原因有多種,即使在您使用的語言版本保證支持它們時也是如此。 其一,正如 John Bollinger 所提到的,以防萬一您想與不支持它們的其他標准保持兼容性。

另一個是,在典型的基於堆棧的實現中,它們消耗的堆棧量在編譯時可能是未知的,或者不受信任的用戶可能會影響,並且此類實現通常沒有很好的檢測方法或從堆棧溢出中恢復。 例如,出於這個原因,Linux kernel 開發人員決定不應在 kernel 中使用 VLA, 使用-Wvla有助於他們強制執行此操作。

這些問題肯定不會適用於每個程序,這就是為什么-Wvla選項是一個選項 無論出於何種原因,如果您想了解 VLA 在您的程序中的使用情況,您可以將其打開,如果您不這樣做,則可以將其關閉。 您選擇使用-Weverything來打開所有存在的警告。 這個標志並不是真正打算對程序員有用,因為正如您所注意到的,它會打開許多警告,這些警告僅在某些情況下對知道他們需要它們的人有用。 它的意思是幫助調試編譯器本身。

因此,實際上,您已經告訴編譯器“發出所有可能的警告,即使它們與我的情況無關”,現在您問為什么收到與您的情況無關的警告:- )

符合 C99 的實現必須支持 VLA,但使用-Weverything啟用所有警告意味着請編譯器告訴我任何可能造成問題的信息 在潛在的問題中有許多一致的結構:

  • VLA 可能會給不完全符合規范的實現帶來可移植性問題,其中有很多。 使用-Wno-vla禁用此警告。
  • 某些運算符組合可能是由於程序員錯誤或對有時違反直覺的相對優先級的混淆造成的。 該表達式仍然符合 C 標准,但編譯器會發出警告,程序員可以添加括號來防止警告。
  • 測試表達式中的賦值是一致的表達式,但編譯器會發出警告,因為它們可能是簡單的拼寫錯誤,其中==被錯誤拼寫為=
  • 未使用的變量不是錯誤,但會在-Weverything下產生警告

清單還在繼續。 如果您要求更多警告(在大多數情況下這可以挽救生命),您可能需要改進CFLAGS以禁用某些選定的警告,例如-Wno-vla以編譯您的程序(如果您確實有意使用 VLA)。

暫無
暫無

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

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