2017-02-20 40 views
46

Глядя на this вопрос и попробовать некоторые из кода:Почему в C не работают несколько операторов декремента, когда они работают на C++?

int x = 100; 

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

я пытался компилировать с gcc и получил следующее сообщение об ошибке:

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

Но компиляция с g++ работ. Почему этот код действителен в C++, но не C?

+75

Поскольку C и C++ - это два разных языка. Другими словами, C и C++ не являются одним и тем же языком. –

+1

Поскольку оператор down '<-' может растягиваться на C++ много раз, если вы хотите быстрее уменьшить: '<----' is downtoby2, '<-------------- ------ 'is downtoby10 – chqrlie

+4

@chqrlie Циркулярное рассуждение. В: Почему вода выходит из моего крана, а не Пепси? A: Поскольку краны можно использовать для легкого доступа к воде. – immibis

ответ

85

В C --x это значение, а не значение lvalue. Его эффект заключается в уменьшении x и вычислении на вновь присвоенное значение x. Поскольку --x не является значением lvalue, оно не может быть уменьшено.

В C++, --x - это значение lvalue, а не rvalue. Его эффект заключается в уменьшении x и оценивании до x как lvalue. Так как --x снова является значением lvalue, его можно снова уменьшить.

Причина, по которой для --x имеет значение lvalue в C++, заключается в том, что C++ вводил ссылочные типы. Учитывая

void f(int &); 
int i; 

может иметь смысл называть f(--i), который проходит i по ссылке после декремента его.

Поскольку C не имеет ссылочных типов, в --i есть небольшая точка, являющаяся значением lvalue. Исторически это никогда не было, и в отличие от C++, C никогда не получал веских оснований менять правила.

Обратите внимание, что C++ требует более обширных изменений, чем принятие --x lvalue, чтобы фактически позволить ему работать. Создание --x lvalue, без чего-либо еще, приведет к неопределенному поведению --x, поскольку между модификацией до x и последующим преобразованием lvalue-to-value не будет точки последовательности. Еще более ясно, поэтому для ----x. C++ должен был изменить правила последовательности, чтобы заставить его работать. В C изменения правил последовательности могут привести к тому, что существующие компиляторы будут соответствовать новым правилам, поэтому такие модификации, вероятно, будут отвергнуты, если не будет большой выгоды.

+8

Вы все еще можете сказать что-то вроде 'f (& - x)'. Я не уверен, что я покупаю вашу причину, почему «нет смысла» в C. –

+4

@ KerrekSB Справедливая точка, но все еще мало смысла. Я бы сказал, что 'f (& - x)' с меньшей вероятностью будет тем, что на самом деле хочет написать, чем 'f (- x)'. Несмотря на это, у C также есть проблема, что изменения в правилах будут проблематичными для существующих реализаций, я добавил немного об этом. – hvd

+0

C++ не требовал каких-либо изменений последовательности, чтобы сделать '--x' значение lvalue. Правило pre-C++ 11 о точках последовательности относится к чтению и записи, а не к преобразованиям lvalue-to-rvalue. –

 Смежные вопросы

  • Нет связанных вопросов^_^