c - _Generic 表达式中指向 VLA 类型控制表达式的指针

标签 c c11 variable-length-array

为什么这个静态断言不会在主要编译器上触发?

void test(int x){
    _Static_assert(_Generic( (char(*)[x])0, 
    char (*)[1]: 1, default: 0),"");
}

https://gcc.godbolt.org/z/E67a79oPT

指向可变长度数组的指针应该与指向固定长度数组的指针兼容吗?

最佳答案

它们实际上是兼容的。

首先,C standard 的第 6.7.6.2p6 节关于数组类型的兼容性说明如下:

For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value. If the two array types are used in a context which requires them to be compatible, it is undefined behavior if the two size specifiers evaluate to unequal values.

由此,有一个要求,如果两个数组大小都是整数常量表达式(即都不是 VLA),那么它们必须相同。但是,如果一个是 VLA,则这不适用,因此它们兼容。

此外,第 6.2.7p3 节说明了有关复合类型的以下内容:

A composite type can be constructed from two types that are compatible; it is a type that is compatible with both of the two types and satisfies the following conditions:

  • If both types are array types, the following rules are applied:
    • If one type is an array of known constant size, the composite type is an array of that size.
    • Otherwise, if one type is a variable length array whose size is specified by an expression that is not evaluated, the behavior is undefined.
    • Otherwise, if one type is a variable length array whose size is specified, the composite type is a variable length array of that size.
    • Otherwise, if one type is a variable length array of unspecified size, the composite type is a variable length array of unspecified size.
    • Otherwise, both types are arrays of unknown size and the composite type is an array of unknown size. The element type of the composite type is the composite type of the two element types.

这意味着当比较类型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),"");
}

您会收到编译错误,因为控制表达式与多个选项兼容,即使这些选项彼此不兼容也是如此。

关于c - _Generic 表达式中指向 VLA 类型控制表达式的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70808334/

相关文章:

C:从函数返回一个字符串?

c++ - __func__ 外部函数定义

c++ - 使用非常量函数参数初始化数组

c++ - 没有匹配的函数可供调用

c - 仅在使用 clang 10 编译时出现 strsep 之后的段错误

c - 使用c中的函数的高级科学计算器

c++ - 使用 Makefile 编译失败但在命令行中成功

c - C中整数的快速符号

c - C11 表达式中的赋值运算符排序

c - 在编译时验证宏参数大小