sizeof有两个论点

Joh*_*ohn 37 c c++ arrays pointers comma-operator

在C++ IS的C.1.3(2003.它也在C++ 11 IS中),该标准指出了ISO C和C++之间的差异; 即,为

char arr[100];
Run Code Online (Sandbox Code Playgroud)

sizeof(0, arr)以C语言返回sizeof(char*),但100在C++中.

我找不到sizeof两个参数的文档.明显的后备是逗号运算符,但我不这么认为:sizeof(arr)在C中100; sizeof(0, arr)sizeof(char*).两个sizeof(0, arr)sizeof(arr)100在C++中.

在这种情况下,我可能会忽略IS的重点.有人可以帮忙吗?这类似于09年讨论的问题,但没有人提到IS,我认为没有给出正确的答案.


编辑:实际上,IS正在谈论逗号运算符.因此,出于某种原因,在C中(0, arr)返回a char*,但char[100]在C++中返回a .为什么?

Naw*_*waz 48

在C中,逗号操作符不产生左值,因此该阵列arr是一个左值衰变到指针类型,是一个右值(在这种情况下).因此,由于左值到右值的转换,所以sizeof(0,arr)相当于.sizeof(char*)

但在C++中,逗号运算符会生成左值.没有左值到右值的转换.所以 sizeof(0,arr)保持不变,相当于sizeof(char[100]).

顺便说一下,sizeof它不是一个功能,它是一个操作员.所以以下是完全有效的C++(和C,如果你想象printf的话cout):

int a[100], b[200], c[300], d[400];
cout << sizeof(a,b,c,d) << endl;
Run Code Online (Sandbox Code Playgroud)

演示:http://www.ideone.com/CtEhn

你可能会认为我已经通过了4个操作数,sizeof但这是错误的.sizeof操作上,结果逗号操作符.而且由于许多逗号运算符,您会看到许多操作数.

带有3个逗号运算符的4个操作数; 就像在1+2+3+4里面一样,有3个操作员,4个操作数.

以上等同于以下内容(在C++ 0x中有效):

auto & result = (a,b,c,d); //first all comma operators operate on the operands.
cout << sizeof (result) << endl; //sizeof operates on the result
Run Code Online (Sandbox Code Playgroud)

演示:http://www.ideone.com/07VNf

所以它是逗号运算符,让你觉得有很多参数.这里的逗号是一个运算符,但在函数调用中,逗号不是运算符,它只是简单的参数分隔符.

function(a,b,c,d); //here comma acts a separator, not operator.
Run Code Online (Sandbox Code Playgroud)

所以sizeof(a,b,c,d)操作上结果的,运营商,正是以同样的方式,sizeof(1+2+3+4)在工作类型的结果的+运营商.

另请注意,您无法编写sizeof(int, char, short),正是因为逗号运算符无法对类型进行操作 .它仅以价值运作.我认为,它sizeof是C和C++中唯一可以在类型上运行的运算符.在C++中,还有一个可以对类型进行操作的运算符.它的名字是typeid.

  • 关于最后一段:C++中的`new`运算符也适用于类型. (4认同)

Pup*_*ppy 25

在C中,然后数组衰减为指针,因为逗号运算符与rvalues和lvalues的关系不同(不是唯一可以找到这种差异的地方).在C++中,数组保持一个数组,产生正确的结果.


AnT*_*AnT 6

它是逗号运算符.而你所谈论的差异与完全无关sizeof.区别在于左值到右值,数组到指针以及C和C++语言之间类似的衰减行为.

在这方面,C语言相当触发快乐:数组几乎立即衰减到指针(除了极少的特定上下文),这就是0, arr表达式的结果具有char *类型的原因.它相当于0, (char *) arr.

在C++语言中,数组保持它们的"数组"更长.当在,运算符数组的上下文中使用时,不会衰减为指针(并且左值不会衰减为rvalues),这就是为什么在C++中0, arr表达式的类型仍然存在char[100].

这就是解释该sizeof示例中行为差异的原因.?:运算符是运算符的另一个示例,它演示了衰减行为的类似差异,即sizeof(0 ? arr : arr)在C和C++中会给出不同的结果.基本上,这一切都源于C运算符通常不保留其操作数的左值.可以使用许多运算符来演示此行为.


Lig*_*ica 5

这不是sizeof两个论点.sizeof是一个操作员,而不是一个功能.

考虑这(0, arr)是一个使用逗号运算符的表达式,其他一切都落到了位置.


Sha*_*our 5

了解这里可能发生的情况的最佳方法是查看标准中的语法。如果我们查看 C99 标准草案6.5.3 一元运算符第1段,我们可以看到 sizeof 的语法是:

sizeof unary-expression
sizeof ( type-name )
Run Code Online (Sandbox Code Playgroud)

所以第二个不适用,但是sizeof unary-expression在这种情况下如何应用呢?如果我们查看标准草案中的A.2.1 “表达式”部分并像这样完成语法:

unary-expression -> postfix-expression -> primary-expression -> ( expression )
Run Code Online (Sandbox Code Playgroud)

我们得到了表达式周围的括号,现在我们只需查看逗号运算符部分中的逗号运算符的语法,我们就会看到:6.5.17

expression:
  assignment-expression
  expression , assignment-expression
Run Code Online (Sandbox Code Playgroud)

所以我们现在有:

sizeof( expression , assignment-expression )
                   ^
                   |
                   comma operator
Run Code Online (Sandbox Code Playgroud)

表达式赋值表达式都可以将我们带到具有以下语法的主表达式:

primary-expression:
  identifier
  constant
  string-literal
  ( expression )
Run Code Online (Sandbox Code Playgroud)

0是一个常量并且arr是一个标识符,所以我们有:

 sizeof( constant , identifier )
Run Code Online (Sandbox Code Playgroud)

那么逗号运算符在这里做什么呢?6.5.172节说:

逗号运算符的左操作数被计算为 void 表达式;评估后有一个序列点。然后计算正确的操作数;结果有其类型和值。97)

由于逗号运算符不是数组不转换为指针的例外情况之一,因此它会产生一个指针(这在第 1.5 节中介绍) 6.3.2.1 这在左值、数组和函数指示符),这意味着我们最终得到:

sizeof( char * )
Run Code Online (Sandbox Code Playgroud)

C++中,语法非常相似,因此我们在相同的位置结束,但逗号运算符的工作方式不同。C++ 标准草案部分5.18 逗号运算符说:

[...]结果的类型和值是右操作数的类型和值;结果与其右操作数具有相同的值类别[...]

所以数组到指针的转换不是必需的,所以我们最终得到:

sizeof( char[100] ) 
Run Code Online (Sandbox Code Playgroud)