哎呀!逗号运算符是C ++标准中最难理解的! [英] Oops! Comma operator is the hardest to understand in the C++ standard!

查看:122
本文介绍了哎呀!逗号运算符是C ++标准中最难理解的!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在标准的5.3.3.4中,该标准规定了左值 - 后 -

rvalue(4.1),数组到指针(4.2)和函数到指针 (4.3)

标准转换不适用于sizeof的操作数。


我认为这个规则很容易理解。因为我可以找到应用规则的

背景如下。


(1)

int * p = 0;

int b1 = sizeof(* p); //好的,b1 = 4,* p不会被评估。


(2)

int array [2];

int b2 = sizeof(array); //好的,b2 = 8,数组不会自动转换为
转换为指向int的指示

(3)

int b3 = sizeof(strlen); //错误,strlen不会自动

转换为函数指针。


到目前为止,一切都是可以理解的。

==========================================


但是,在标准的5.18中,我发现了一个类似于逗号的规则

运算符:左值到右值(4.1),数组到指针(4.2),和

函数到指针(4.3)标准转换不适用于

左表达式。


I我尽力猜测后一条规则的原因,但失败了。

甚至,我找不到一个检验规则的例子。


(1 )

int a,b;

a = b,a ++; //编译没问题。为什么?因为a = b将导致

左值到右值的转换。


(2)


int a [2];

int * b;

b = a,b ++; //编译没问题。为什么?因为b = a会导致数组 -

指针转换。


(3)

typedef int(* FP )(int,int);


int Hello(int a,int b)

{

返回a + b;

}


FP pf;

pf =你好,(* pf)(1,2); //编译没问题。为什么?因为pf = Hello

会导致函数到指针的转换。


我一直在想这个问题好几天了,现在我感到迷茫

并且无能为力。谁能给我一些提示?任何帮助都将非常高兴

赞赏!

解决方案

Lighter写道:


在标准的5.3.3.4中,标准规定了左值 -

rvalue(4.1),数组到指针(4.2),和函数到指针(4.3)

标准转换不适用于sizeof的操作数。


我认为这个规则很容易理解。因为我可以找到应用规则的

背景如下。


(1)

int * p = 0;

int b1 = sizeof(* p); //好的,b1 = 4,* p不会被评估。


(2)

int array [2];

int b2 = sizeof(array); //好的,b2 = 8,数组不会自动转换为
转换为指向int的指示

(3)

int b3 = sizeof(strlen); //错误,strlen不会自动

转换为函数指针。


到目前为止,一切都是可以理解的。

==========================================


但是,在标准的5.18中,我发现了一个类似于逗号的规则

运算符:左值到右值(4.1),数组到指针(4.2),和

函数到指针(4.3)标准转换不适用于

左表达式。


I我尽力猜测后一条规则的原因,但失败了。

甚至,我找不到一个检验规则的例子。


(1 )

int a,b;

a = b,a ++; //编译没问题。为什么?因为a = b将导致

左值到右值的转换。



*里面*逗号左侧的[赋值]表达式

任何转换都无关紧要AFA 5.18。但是,作为

,赋值的结果(返回值为int&)''(a = b)''不是
转换为r值。这就是5.18所说的。


>

(2)


int a [2];

int * b;

b = a,b ++; //编译没问题。为什么?因为b = a会导致

数组到指针的转换。



再次,你关心安全重写这个


b = a;

b,b ++;


它有_precisely_同样的效果。在第一个(赋值)

表达式语句中,''a''被转换为指针。但是,在逗号的左侧是b,b(对int的指针的引用)

不会被转换成任何东西。


>

(3)

typedef int(* FP)(int,int);


int Hello(int a,int b)

{

返回a + b;

}


FP pf;

pf =你好,(* pf)(1,2); //编译没问题。为什么?因为pf = Hello

将导致函数到指针的转换。



同样的事情。你很困惑_where_转换发生了。首先评估逗号运算符的

操作数,并在此期间进行评估,任何事情都会发生。但是在评估之后,对于
,评估的结果将不会是b $ b另外还要进行左值到右值的转换。


>

几天来我一直在想这个问题,现在我感到很遗憾

和无能为力。谁能给我一些提示?任何帮助将是非常高的

赞赏!



见上文。


V

-

请在通过电子邮件回复时删除大写''A'

我没有回复最热门的回复,请不要问

2007年6月21日星期四09:15:01 -0700,Lighter写道:


但是,在标准的5.18中,我发现了类似的规则在逗号上

运算符:"左值到右值(4.1),数组到指针(4.2),和

函数到指针(4.3)标准转换不适用于

左表达式。


我尽力猜测后一条规则的原因,但失败了。 />
甚至,我找不到一个检验规则的例子。



由于逗号运算符的左表达式的值被丢弃

无论如何转换它没有任何意义。我甚至不知道如何检查转换是否发生。


(1)

int a,b;

a = b,a ++; //编译没问题。为什么?因为a = b将导致

左值到右值的转换。



这里逗号运算符的左表达式是a = b。而且不是转换成
。转换的是b,它是

赋值的右侧。


[...更多分配rhs和逗号的例子左表达

混淆...]



-

Markus Schoder


非常感谢,Victor。


据我所知,C99并没有提供规则。我的困惑在于制定这样一条规则的理由。

你能给我一个例子

说明一些转换应用于左表达式

(或左操作数)?我找不到这样的例子。如果有

没有这样的例子。为什么标准提供这样的规则?


再次感谢。



In 5.3.3.4 of the standard, the standard provides that "The lvalue-to-
rvalue(4.1), array-to-pointer(4.2),and function-to-pointer(4.3)
standard conversions are not applied to the operand of sizeof."

I think this rule is easy to understand. Because I can find the
contexts of applying the rule as follows.

(1)
int* p = 0;
int b1 = sizeof(*p); // OK, b1 = 4, *p would not be evaluated.

(2)
int array[2];
int b2 = sizeof(array); // OK, b2 = 8, array will not be automatically
converted to a pointer to int

(3)
int b3 = sizeof(strlen); // error, strlen will not be automatically
converted to a function pointer.

So far, everything is understandable.
==========================================

However, In 5.18 of the standard, I find a similar rule on comma
operator: "The lvalue-to-rvalue(4.1), array-to-pointer(4.2),and
function-to-pointer(4.3) standard conversions are not applied to the
left expression."

I tried my best to guess the reason of the latter rule, but failed.
Even, I could not find an example to examine the rule.

(1)
int a, b;
a = b, a++; // compiling is OK. Why? Because a = b will cause an
lvalue-to-rvalue conversion.

(2)

int a[2];
int* b;
b = a, b++; // compiling is OK. Why? Because b = a will cause an array-
to-pointer conversion.

(3)
typedef int (*FP)(int, int);

int Hello(int a, int b)
{
return a + b;
}

FP pf;
pf = Hello, (*pf)(1, 2); // compiling is OK. Why? Because pf = Hello
will cause a function-to-pointer conversion.

I have been thinking the problem for several days, and now I feel lost
and clueless. Who can give me some tips? Any help will be highly
appreciated!

解决方案

Lighter wrote:

In 5.3.3.4 of the standard, the standard provides that "The lvalue-to-
rvalue(4.1), array-to-pointer(4.2),and function-to-pointer(4.3)
standard conversions are not applied to the operand of sizeof."

I think this rule is easy to understand. Because I can find the
contexts of applying the rule as follows.

(1)
int* p = 0;
int b1 = sizeof(*p); // OK, b1 = 4, *p would not be evaluated.

(2)
int array[2];
int b2 = sizeof(array); // OK, b2 = 8, array will not be automatically
converted to a pointer to int

(3)
int b3 = sizeof(strlen); // error, strlen will not be automatically
converted to a function pointer.

So far, everything is understandable.
==========================================

However, In 5.18 of the standard, I find a similar rule on comma
operator: "The lvalue-to-rvalue(4.1), array-to-pointer(4.2),and
function-to-pointer(4.3) standard conversions are not applied to the
left expression."

I tried my best to guess the reason of the latter rule, but failed.
Even, I could not find an example to examine the rule.

(1)
int a, b;
a = b, a++; // compiling is OK. Why? Because a = b will cause an
lvalue-to-rvalue conversion.

*Inside* the [assignment] expression on the left side of the comma
any conversion does not matter AFA 5.18 is concerned. However, as
the result of the assignment (with return value int&) ''(a=b)'' is NOT
onverted to r-value. That''s what 5.18 is talking about.

>
(2)

int a[2];
int* b;
b = a, b++; // compiling is OK. Why? Because b = a will cause an
array- to-pointer conversion.

Again, you care safely rewrite this as

b = a;
b, b++;

it has _precisely_ the same effect. In the first (assignment)
expression statement, ''a'' is converted to a pointer. However, at
the left side of the comma, ''b'' (a reference to a pointer to int)
is not converted into anything.

>
(3)
typedef int (*FP)(int, int);

int Hello(int a, int b)
{
return a + b;
}

FP pf;
pf = Hello, (*pf)(1, 2); // compiling is OK. Why? Because pf = Hello
will cause a function-to-pointer conversion.

Same thing. You''re confusing _where_ the conversion happens. The
operands of the comma operator are evaluated first, and during that
evaluation anything will happen what''s supposed to happen. But right
after that evaluation, the result of that evaluation will NOT be
additionally subjected to lvalue-to-rvalue conversion.

>
I have been thinking the problem for several days, and now I feel lost
and clueless. Who can give me some tips? Any help will be highly
appreciated!

See above.

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask


On Thu, 21 Jun 2007 09:15:01 -0700, Lighter wrote:

However, In 5.18 of the standard, I find a similar rule on comma
operator: "The lvalue-to-rvalue(4.1), array-to-pointer(4.2),and
function-to-pointer(4.3) standard conversions are not applied to the
left expression."

I tried my best to guess the reason of the latter rule, but failed.
Even, I could not find an example to examine the rule.

Since the value of the left expression of the comma operator is discarded
anyway there would be no purpose in converting it. I cannot even see how
one would check whether the conversion happens or not.

(1)
int a, b;
a = b, a++; // compiling is OK. Why? Because a = b will cause an
lvalue-to-rvalue conversion.

Here the left expression of the comma operator is "a = b" and is not
converted. What is converted is b which is the right hand side of an
assignment.

[... more examples of assignment rhs and comma left expression
confusion ...]

--
Markus Schoder


Thank you very much, Victor.

As far as I know, C99 didn''t provide the rule. My confusion lies in
the reason for making such a rule. Could you give me an example
illustrating that some conversions are applied on the left expression
(or the left operand)? I could not find such an example. If there were
no such an example. Why did the standard provide such a rule?

Thanks again.



这篇关于哎呀!逗号运算符是C ++标准中最难理解的!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆