为什么多个减量操作符在c++中工作时不能在C中工作呢?

时间:2022-01-26 20:05:57

Looking at this question and trying out some of the code:

看看这个问题,并尝试一些代码:

int x = 100;

while ( 0 <-------------------- x )
{
    printf("%d ", x);
}

I attempted to compile with gcc and got the following error:

我尝试用gcc编译,得到如下错误:

file.c: In function 'main':
file:c:10:27: error: lvalue required as decrement operand
 while ( 0 <-------------------- x )

But compiling with g++ works. Why is this code valid in C++ but not C?

但是用g++进行编译。为什么这些代码在c++中有效,而在C中无效?

1 个解决方案

#1


86  

In C, --x is a value, not an lvalue. Its effect is to decrement x, and evaluate to the newly assigned value of x. Since --x is not an lvalue, it cannot be decremented.

在C中,x是一个值,不是lvalue。它的作用是递减x,并对x的新赋值求值,因为-x不是lvalue,所以不能递减。

In C++, --x is an lvalue, not an rvalue. Its effect is to decrement x, and evaluate to x as an lvalue. Since --x is an lvalue again, it can be decremented again.

在c++中,x是一个lvalue,而不是一个rvalue。它的作用是使x变小,并将x作为一个lvalue。因为-x是lvalue,它可以再次递减。

The reason why it makes sense for --x to be an lvalue in C++ is because C++ introduced reference types. Given

x在c++中是lvalue的原因是因为c++引入了引用类型。鉴于

void f(int &);
int i;

it may make sense to call f(--i), which passes i by reference after decrementing it.

调用f(- i)可能是有意义的,它在递减之后通过引用传递i。

Since C doesn't have reference types, there's little point in --i being an lvalue. Historically, it never was, and unlike C++, C never gained a compelling reason to change the rules.

因为C没有引用类型,所以i是lvalue。从历史上看,它从来都不是,而且不像c++, C从来没有得到一个令人信服的理由去改变规则。

Note that C++ required more extensive changes than making --x an lvalue to actually let it work. Making --x an lvalue, without anything else, would make --x undefined behaviour, because there would not be a sequence point between the modification to x and the subsequent lvalue-to-value conversion. Even more clearly so for ----x. C++ had to modify the sequencing rules to make it work. In C, modifications to the sequencing rules might cause problems for existing compilers to conform to the new rules, so such modifications would likely be rejected unless there's a big benefit.

注意,c++需要进行比lvalue更广泛的更改——x才能让它工作。使x为lvalue,不需要任何其他东西,就会使x为无定义行为,因为在对x的修改和随后的lvalue-to-value转换之间没有一个序列点。更清楚的是——x。c++必须修改排序规则以使其工作。在C语言中,对排序规则的修改可能会导致现有编译器在遵守新规则时出现问题,因此这种修改很可能被拒绝,除非有很大的好处。

#1


86  

In C, --x is a value, not an lvalue. Its effect is to decrement x, and evaluate to the newly assigned value of x. Since --x is not an lvalue, it cannot be decremented.

在C中,x是一个值,不是lvalue。它的作用是递减x,并对x的新赋值求值,因为-x不是lvalue,所以不能递减。

In C++, --x is an lvalue, not an rvalue. Its effect is to decrement x, and evaluate to x as an lvalue. Since --x is an lvalue again, it can be decremented again.

在c++中,x是一个lvalue,而不是一个rvalue。它的作用是使x变小,并将x作为一个lvalue。因为-x是lvalue,它可以再次递减。

The reason why it makes sense for --x to be an lvalue in C++ is because C++ introduced reference types. Given

x在c++中是lvalue的原因是因为c++引入了引用类型。鉴于

void f(int &);
int i;

it may make sense to call f(--i), which passes i by reference after decrementing it.

调用f(- i)可能是有意义的,它在递减之后通过引用传递i。

Since C doesn't have reference types, there's little point in --i being an lvalue. Historically, it never was, and unlike C++, C never gained a compelling reason to change the rules.

因为C没有引用类型,所以i是lvalue。从历史上看,它从来都不是,而且不像c++, C从来没有得到一个令人信服的理由去改变规则。

Note that C++ required more extensive changes than making --x an lvalue to actually let it work. Making --x an lvalue, without anything else, would make --x undefined behaviour, because there would not be a sequence point between the modification to x and the subsequent lvalue-to-value conversion. Even more clearly so for ----x. C++ had to modify the sequencing rules to make it work. In C, modifications to the sequencing rules might cause problems for existing compilers to conform to the new rules, so such modifications would likely be rejected unless there's a big benefit.

注意,c++需要进行比lvalue更广泛的更改——x才能让它工作。使x为lvalue,不需要任何其他东西,就会使x为无定义行为,因为在对x的修改和随后的lvalue-to-value转换之间没有一个序列点。更清楚的是——x。c++必须修改排序规则以使其工作。在C语言中,对排序规则的修改可能会导致现有编译器在遵守新规则时出现问题,因此这种修改很可能被拒绝,除非有很大的好处。