為什么這個靜態斷言不會在主要編譯器上觸發?
void test(int x){
_Static_assert(_Generic( (char(*)[x])0,
char (*)[1]: 1, default: 0),"");
}
https://gcc.godbolt.org/z/E67a79oPT
指向可變長度陣列的指標是否應該與指向固定長度陣列的指標兼容?
uj5u.com熱心網友回復:
它們實際上是兼容的。
首先,C 標準的第 6.7.6.2p6 節對陣列型別的兼容性做了如下說明:
對于要兼容的兩個陣列型別,兩者都應具有兼容的元素型別,并且如果兩個大小說明符都存在并且都是整數常量運算式,則兩個大小說明符應具有相同的常量值。如果在需要它們兼容的背景關系中使用這兩種陣列型別,則如果這兩個大小說明符計算為不相等的值,則這是未定義的行為。
因此,如果兩個陣列大小都是整數常量運算式(即兩者都不是 VLA),則要求它們必須相同。但是,如果一個是 VLA,則這不適用,因此它們可以兼容。
此外,第 6.2.7p3 節對復合型別進行了以下說明:
復合型別可以由兩種兼容的型別構成;它是與這兩種型別都兼容并滿足以下條件的型別:
- 如果兩種型別都是陣列型別,則應用以下規則:
- 如果一種型別是已知常量大小的陣列,則復合型別是該大小的陣列。
- 否則,如果一種型別是可變長度陣列,其大小由未計算的運算式指定,則行為未定義。
- 否則,如果一種型別是指定了大小的可變長度陣列,則復合型別是該大小的可變長度陣列。
- 否則,如果一種型別是未指定大小的可變長度陣列,則復合型別是未指定大小的可變長度陣列。
- 否則,兩種型別都是未知大小的陣列,復合型別是未知大小的陣列。復合型別的元素型別是兩種元素型別的復合型別。
這意味著在比較型別char(*)[x]和時char(*)[1],它們的復合型別是char(*)[1]。這也意味著它char(*)[x]與任何指向固定大小陣列的指標兼容char。因此,如果您的函式如下所示:
void test(int x){
_Static_assert(_Generic( (char(*)[x])0,
char (*)[2]: 2,
char (*)[1]: 1,
default: 0),"");
}
您會收到編譯錯誤,因為控制運算式與多個選項兼容,即使這些選項彼此不兼容。
uj5u.com熱心網友回復:
它們是兼??容的。C 2018 6.7.6.2 6 說“對于兩個兼容的陣列型別,兩者都應具有兼容的元素型別,并且如果兩個大小說明符都存在,并且都是整數常量運算式,那么兩個大小說明符應具有相同的常量值......”因為兩個大小說明符都是整數常量運算式是不正確的,具有相同值的要求不適用。
指標兼容性繼承自指向的型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/418546.html
標籤:
上一篇:C外部錯誤和1個警告
