sizeof 接受两个参数
在 C++ IS 的 C.1.3 中(2003 年。C++11 IS 中也有),该标准指出了 ISO C 和 C++ 之间的区别;也就是说,
char arr[100];
sizeof(0, arr)
在 C 中返回 sizeof(char*)
,但在 C++ 中返回 100
。
我找不到关于采用两个参数的 sizeof
的文档。明显的后备方法是逗号运算符,但我不这么认为:C 中的 sizeof(arr)
是 100
; sizeof(0, arr)
是 sizeof(char*)
。在 C++ 中,sizeof(0, arr)
和 sizeof(arr)
均为 100
。
在这种情况下,我可能错过了 IS 的全部要点。有人可以帮忙吗?这与09年讨论过的问题类似,但没有人提到IS,我认为没有给出正确答案。
编辑:实际上,IS 正在谈论逗号运算符。因此,出于某种原因,(0, arr)
在 C 中返回 char*
,但在 C++ 中返回 char[100]
。为什么?
In C.1.3 of the C++ IS (2003. It's in the C++11 IS, too), the standard points out a difference between ISO C and C++; namely, for
char arr[100];
sizeof(0, arr)
returns sizeof(char*)
in C, but 100
in C++.
I can find no documentation for sizeof
taking two arguments. The obvious fallback is the comma operator, but I don't think so: sizeof(arr)
in C is 100
; sizeof(0, arr)
is sizeof(char*)
. Both sizeof(0, arr)
and sizeof(arr)
are 100
in C++.
I may be missing the whole point of the IS in this context. Can anyone help? This is similar to a question discussed back in '09, but no one referred to the IS, and I don't think the correct answer was given.
Edit: Actually, the IS is talking about the comma operator. So, for some reason (0, arr)
returns a char*
in C, but a char[100]
in C++. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在 C 中,逗号运算符不会产生左值,因此作为左值的数组 arr 会分解为作为右值的指针类型(在本例中)。因此,由于左值到右值的转换,
sizeof(0,arr)
等同于sizeof(char*)
。但在 C++ 中,逗号运算符会生成左值。没有左值到右值的转换。所以
sizeof(0,arr)
保持不变,相当于sizeof(char[100])
。顺便说一句,
sizeof
不是一个函数,它是一个运算符。因此,以下是完全有效的 C++(和 C,如果您想象printf
而不是cout
):演示:http://www.ideone.com/CtEhn
您可能认为我已将 4 个操作数传递给
sizeof
,但这是错误的。sizeof
对逗号运算符的结果进行运算。这是因为有许多逗号运算符,您会看到许多操作数。4 个操作数和 3 个逗号运算符;就像
1+2+3+4
中一样,有 3 个运算符、4 个操作数。以上等价于以下内容(在 C++0x 中有效):
演示 : http://www.ideone.com /07VNf
因此,正是逗号运算符让您感觉有很多参数。这里逗号是一个运算符,但在函数调用中,逗号不是一个运算符,它只是参数分隔符。
因此
sizeof(a,b,c,d)
对,
运算符结果的类型进行运算,完全相同的方式,< code>sizeof(1+2+3+4) 对+
运算符结果的类型进行运算。另请注意,您不能编写
sizeof(int, char, short)
,正是因为逗号运算符无法对类型。它仅对值起作用。我认为,sizeof
是 C 和 C++ 中唯一可以对类型进行操作的运算符。在 C++ 中,还有一个可以对类型进行操作的运算符。它的名称是typeid
。In C, comma operator doesn't produce an lvalue, consequently the array
arr
which is an lvalue decays into a pointer type which is a rvalue (in this case). Sosizeof(0,arr)
becomes equivalent tosizeof(char*)
, due to lvalue-to-rvalue conversion.But in C++, comma operator produces an lvalue. There is no lvalue-to-rvalue conversion. So
sizeof(0,arr)
remains same, which is equivalent tosizeof(char[100])
.By the way,
sizeof
is not a function, it's an operator. So the following is completely valid C++ (and C, if you imagineprintf
instead ofcout
):Demo : http://www.ideone.com/CtEhn
You might think that I've passed 4 operands to
sizeof
but that is wrong.sizeof
operates on the result of the comma operators. And its because of the many comma operators you see many operands.4 operands with 3 comma operators; just like in
1+2+3+4
, there're 3 operators, 4 operands.The above is equivalent to the following (valid in C++0x):
Demo : http://www.ideone.com/07VNf
So it's the comma operator which makes you feel that there are many arguments. Here comma is an operator, but in function call, comma is NOT an operator, its simply argument separator.
So
sizeof(a,b,c,d)
operates on the type of the result of,
operators, exactly in the same way,sizeof(1+2+3+4)
operates on the type of the result of+
operators.Also note that you cannot write
sizeof(int, char, short)
, precisely because comma operator cannot operate on types. It operates on value only. I think,sizeof
is the only operator in C and C++, which can operate on types as well. In C++, there is one more operator which can operates on types. Its name istypeid
.在 C 中,由于与右值和左值相关的逗号运算符的不同规范(不是唯一可以找到这种差异的地方),数组正在衰减为指针。在 C++ 中,数组仍然是数组,产生正确的结果。
In C then the array is decaying to a pointer, because of the different specification of the comma operator with relation to rvalues and lvalues (not the only place such a difference can be found). In C++ then the array stays an array, yielding the correct result.
它是一个逗号运算符。而你所说的差异与
sizeof
完全无关。区别实际上在于 C 和 C++ 语言之间的左值到右值、数组到指针以及类似的衰减行为。C 语言在这方面相当容易触发:数组几乎立即衰减为指针(极少数特定上下文除外),这就是为什么
0, arr
表达式的结果具有char *
类型。它相当于0, (char *) arr
。在 C++ 语言中,数组可以更长时间地保留“数组性”。当在
,
上下文中使用时,运算符数组不会衰减为指针(左值不会衰减为右值),这就是为什么在 C++ 中类型为0, arr
表达式仍然是char[100]
。这就是解释该示例中
sizeof
行为差异的原因。?:
运算符是另一个运算符示例,它演示了衰减行为中的类似差异,即sizeof(0 ? arr : arr)
在 C 和 C++ 中会给出不同的结果。基本上,这一切都源于 C 运算符通常不保留其操作数的左值这一事实。可以使用许多运算符来演示这种行为。It is a comma operator. And the difference you are talking about has absolutely nothing to do with
sizeof
. The difference is really in lvalue-to-rvalue, array-to-pointer and similar decay behaviors between C and C++ languages.C language is rather trigger-happy in this regard: arrays decay to pointers practically immediately (with the exception of very few specific contexts), which is why the result of
0, arr
expression haschar *
type. It is equivalent to0, (char *) arr
.In C++ language arrays preserve they "arrayness" much longer. When used in the context of
,
operator arrays don't decay to pointers (and lvalues do not decay to rvalues), which is why in C++ the type of0, arr
expression is stillchar[100]
.This is what explains the difference in
sizeof
behavior in that example.?:
operator is another example of an operator that demonstrates the similar difference in decay behavior, i.e.sizeof(0 ? arr : arr)
will give you different results in C and C++. Basically, it all stems from the fact that C operators don't usually preserve the lvalueness of their operands. A lot of operators can be used to demonstrate this behavior.这不是
sizeof
采用两个参数。sizeof
是一个运算符,而不是一个函数。考虑一下
(0, arr)
是一个使用逗号运算符的表达式,其他一切都就位了。This is not
sizeof
taking two arguments.sizeof
is an operator, not a function.Consider that
(0, arr)
is an expression using the comma operator, and everything else falls into place.了解这里可能发生的情况的最佳方法是查看标准中的语法。如果我们查看 C99 标准草案
6.5.3
一元运算符 段落 1,我们可以看到 sizeof 的语法是:所以第二个一个不适用,但是
sizeof unary-expression
在这种情况下如何应用?如果我们查看标准草案中的A.2.1
表达式 并像这样处理语法:我们得到 表达式 周围的括号,并且现在我们只需查看
6.5.17
部分中的 逗号运算符 语法 逗号运算符 我们就会看到:所以我们现在有:
表达式 和赋值表达式可以将我们带到主表达式,它具有以下语法:
0
是一个常量并且arr
是一个标识符,所以我们有:那么逗号运算符在这里做什么?
6.5.17
段落 2 说:由于逗号运算符不是数组不转换为指针的例外情况之一,因此它会生成一个指针(这在第 < 节中介绍) /em>
6.3.2.1
左值、数组和函数指示符),这意味着我们最终得到:在 C++ 中,语法非常相似,因此我们在同一个地方结束但是逗号运算符的工作方式不同。 C++ 草案标准部分
5.18
逗号运算符 说:,因此不需要数组到指针的转换,因此我们最终得到:
The best way to see what could be going on here is look at the grammar in the standard. If we look at the draft C99 standard section
6.5.3
Unary operators paragraph 1 we can see that the grammar for sizeof is:So the second one does not apply but how does the
sizeof unary-expression
apply in this case? If we look at sectionA.2.1
Expressions from the draft standard and work through the grammar like so:we get the parenthesizes around an expression and now we just have to look at the grammar for comma operator from section
6.5.17
Comma operator and we see:So we have now have:
both expression and assignment-expression can take us to primary-expression which has the following grammar:
and
0
is a constant andarr
is an identifier so we have:So what does the comma operator do here? Section
6.5.17
paragraph 2 says:since the comma operator is not one of the exceptions where a array is not converted to a pointer it yields a pointer(this is covered in section
6.3.2.1
Lvalues, arrays, and function designators) which means we end up with:In C++ the grammar is pretty similar so we end in the same place but the comma operators works differently. The C++ draft standard section
5.18
Comma operator says:so and array-to-pointer conversion is not not required and so we end up with:
sizeof
不接受两个参数。但这也不是一个函数,所以
(...)
不分隔函数参数,它们只是一个语法的可选部分,并强制分组。当你写的时候
sizeof(0, arr)
,sizeof
的参数是单个表达式0,
。带有逗号运算符的单个表达式,用于计算到达
逗号左边的表达式,抛出它的值(但不抛出它的值)
副作用),然后计算逗号右侧的表达式,
并将其值用作完整表达式的值。
我不确定C,但这可能是两者之间的区别
语言。在 C++ 中,不会发生数组到指针的转换,除非
它是需要的;在C中,如果我没记错的话,标准说它
除了在某些情况下之外,总是会发生。包括作为
sizeof
运算符。在这种情况下,由于逗号运算符不对其操作数的类型有限制,
C++ 中不会发生数组到指针的转换。在C中,一个
逗号运算符的操作数未在例外中列出,因此
数组到指针的转换确实发生了。 (在本例中,数组
是逗号运算符的操作数,而不是
sizeof
的操作数。)sizeof
doesn't take two arguments. But it's not a function, either,so the
(...)
don't delimit function arguments, they're just anoptional part of the syntax, and enforce grouping. When you write
sizeof(0, arr)
, the argument tosizeof
is the single expression0,
. A single expression with a comma operator, which evaluates thearr
expression to the left of the comma, throws out its value (but not its
side effects), then evaluates the expression to the right of the comma,
and uses its value as the value of the complete expression.
I'm not sure about C, but this could be a difference between the
langauges. In C++, the array-to-pointer conversion doesn't occur unless
it is needed; in C, if I recall correctly, the standard says that it
always takes place except in certain contexts. Including as the
operator of
sizeof
. In this case, since the comma operator doesn'thave an constraints with regards to the types of its operands, the
array-to-pointer conversion doesn't take place in C++. In C, an
operatand of the comma operator isn't listed in the exceptions, so the
array-to-pointer conversion does take place. (In this case, the array
is an operand of the comma operator, and not of
sizeof
.)正如几位已经说过的,我只想添加一件事,sizeof 是一个采用表达式或强制转换表达式的运算符。
出于这个原因,我养成了在 sizeof only 是强制转换表达式时才写括号的习惯。
我会写,
但
我会用
return
做同样的事情,不带括号,因为它不是函数调用,如果我放括号,那是因为后面的表达式需要它们。As several have already said, and I want to add only one thing, sizeof is an operator taking either an expression or a cast expression.
For this reason I took the habit to write paranthesis to a sizeof only if it is a cast expression.
I will write
but
I do the same with
return
no parenthesis, as it is not a function call, and if I put parenthesis it's because the expression following needs them.