Sizeof 应用于不完整数组类型的参数
对于此代码:
int f(int x[])
{
return sizeof x;
}
GCC 生成:
warning: 'sizeof' on array function parameter 'x' will return size of 'int *'
Clang 生成:
warning: sizeof on array function parameter will return size of 'int *' instead of 'int[]'
问题:如果 x
具有不完整的类型(因为大小不存在),那么它是否期望具有:
error: invalid application of 'sizeof' to incomplete type
Extra:这是否意味着 return 'int *' 的大小
是 GCC/Clang 扩展吗?
For this code:
int f(int x[])
{
return sizeof x;
}
GCC produces:
warning: 'sizeof' on array function parameter 'x' will return size of 'int *'
Clang produces:
warning: sizeof on array function parameter will return size of 'int *' instead of 'int[]'
Question: if x
has incomplete type (since the size is not present), then is it expected to have:
error: invalid application of 'sizeof' to incomplete type
Extra: does it mean that return size of 'int *'
is a GCC/Clang extension?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
作为函数参数的数组实际上是一个指针。来自 C 标准 关于函数声明符:
这意味着:
与此完全相同:
所以
x
确实具有完整的类型并且没有错误。 gcc 和 clang 都有助于生成警告,因为结果可能不是人们所期望的。An array as an argument to a function is actually a pointer. From section 6.7.6.3p7 of the C standard regarding Function Declarators:
This means that this:
Is exactly the same as this:
So
x
does have complete type and there is no error. Both gcc and clang are being helpful in generating a warning as the result might not be what one expects.不管表面上如何,
f
函数的x
参数不是一个不完整的类型。它是一个指针 (int*
),因为任何数组在用作函数的声明参数时在语法上等同于指向数组第一个元素的指针。因此,
sizeof x
表达式的操作数是一个完整类型(指向int
的指针); GNU 和 Clang 编译器给出的警告只是“提醒”您数组到指针的所谓“衰减”。要“验证”上述总计等价性,请添加函数的前向声明,使用
int* x
作为形式参数 - 将有(或应该)没有进一步的警告:Despite appearances, the
x
parameter to yourf
function is not an incomplete type. It is a pointer (int*
), because any array, when used as a declared parameter of a function is syntactically equivalent to a pointer to the array's first element.Thus, the operand of your
sizeof x
expression is a complete type (pointer toint
); the warnings given by the GNU and Clang compilers are merely 'reminding' you of this so-called "decay" of the array to a pointer.To 'verify' the aforementioned total equivalence, add a forward declaration of the function, using
int* x
as the formal parameter – there will be (or should be) no further warning about that:,当尝试确定不完整类型的大小时,这将是 gcc 发出的常见错误消息,但这不是示例代码中发生的情况。
在函数声明的参数列表中,所有声明为数组类型的参数(包括不完整的数组类型)都会调整为具有相应的指针类型。 C17 6.7.6.3/7 中对此进行了描述:
这是源代码的语义问题,而不是运行时转换,尽管它与运行时发生的数组值自动转换为指针相吻合(原则上)。
不。警告消息描述了标准 C 的语义(从今以后)。
就其价值而言,当我计划访问参数时,我倾向于更喜欢示例中的形式,就好像它指向数组的第一个成员一样(通过使用
[]
对其进行索引或执行指针算术上)。特别是,我总是将main
的两参数签名写为:Yes, that would be the usual error message from gcc when one attempts to determine the size of an incomplete type, but that's not what is happening in the example code.
In the parameter list of a function declaration, all parameters declared to have array type -- including incomplete array types -- are adjusted to have corresponding pointer types. This is described in C17 6.7.6.3/7:
That is a question of the semantics of the source code, not a runtime conversion, though it dovetails with the automatic conversion of array values to pointers that happens at runtime (in principle).
No. The warning message describes the semantics of standard C (since forever).
For what it's worth, I tend to prefer the form in your example when I plan to access the parameter as if it pointed to the first member of an array (by indexing it with
[]
or performing pointer arithmetic on it). In particular, I always write the two-parameter signature ofmain
as:当您将数组传递给函数时,实际上是将其地址作为指针传递。在数组上使用 sizeof() 只会返回指针的大小。它不会产生错误,因为
sizeof(int*)
是有效的操作When you pass an array into a function, you are actually passing it's address as a pointer. Using
sizeof()
on the array will only return the size of a pointer. It will not produce an error assizeof(int*)
is a valid operation