为什么对于数组参数的指针衰减似乎不适用于sizeof()?

8
我之前读到了一个问题,由于是与下面这个问题完全相同而被关闭:当函数有一个特定大小的数组参数时,为什么它会被替换成一个指针?以及如何找到指向数组的指针的“sizeof”?但是在阅读了这些内容之后,我仍然不理解sizeof()如何工作。我知道将数组作为参数传递给函数,例如:
  void foo(int a[5])

如果将数组作为参数传递,将导致数组参数衰减为指针。但在上述两个问题链接中,我没有找到一个明确的答案,说明为什么sizeof()函数本身豁免于(或至少表面上豁免于)这种指针衰减行为。如果sizeof()像其他函数一样运作,则

   int a[5] = {1,2,3,4,5};
   cout << sizeof(a) << endl;

如果一切正常,上述输出应该是4而不是20。如果我错过了一些明显的东西,那么这似乎与指针衰减行为相矛盾。很抱歉再次提起这个问题,但尽管多年来一直快乐地使用这个函数而没有真正考虑它,但我确实很难理解为什么会发生这种情况。

3
注意:void foo(int (&a)[5]) 不会导致数组参数退化。重要的是目标,而不是源。 - Xeo
3
“void foo(int a[5])”这种参数形式真的应该被弃用,只允许使用“void foo(int* a)”这种形式,因为前者只会带来混乱。我不在意它会破坏谁的代码。 - Benjamin Lindley
2个回答

16

因为标准规定如下(重点是我加的):

(C99,6.3.2.1p3)“除非它是sizeof运算符或一元& 运算符的操作数,或是用于初始化数组的字符串字面量,否则具有类型“ type的数组”的表达式将被转换为具有类型“指向array对象的初始元素的指针类型”,并且不是左值。”

请注意,对于C ++,标准明确表示大小是数组的大小:

(C++11,5.3.3p2 sizeof)“[...]当应用于数组时,结果是数组中的总字节数。这意味着n个元素的数组的大小是一个元素的大小乘以n。”


在C++中,规则略有不同,它还有另一种情况,即将数组表达式绑定到数组引用时不会发生衰减。但这些都是奇怪的事情。另请参阅https://dev59.com/tnA75IYBdhLWcg3wT3H8。 - MSalters

7

sizeof 是一个运算符,而不是一个函数。它还是一个具体的运算符。如果它是一个表达式,甚至括号都不是必需的:

int a;
sizeof (int); //needed because `int` is a type
sizeof a; //optional because `a` is an expression
sizeof (a); //^ also works 

正如您所见,它也在优先级图表中。它还是不可重载的运算符之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接