2013-07-21 2 views
4

Вероятно, как и многие, я напечатал эту опечаткуОшибка компиляции, сравнивающая целое число со строкой?

int a = 0; 
cout << a < " "; //note the '<' 

Однако компилятор MSVC++ бросил только предупреждение

предупреждение C4552: '<': оператор не имеет никакого эффекта; ожидаемый оператор с побочный эффект

, хотя я ожидал ошибки компиляции. Действительно ли это стандартный код жалобы? Происходит ли какое-либо неявное преобразование или перегрузка типов, которые делают код действительным? Я также путаю ли < оператора сравнения строки " " с целым числом a или с результатом cout << a

Связанная SO постом является here.

+0

Используемый вами компилятор принимает сравнения указателей и интегральных типов, но стандарт запрещает это. При необходимости обновите или измените компилятор –

+1

@ a.lasram И как будет работать макрос «NULL», если он не будет? – kfsone

+1

@ a.lasram Это не так. Вы перепутали приоритет. –

ответ

7

Оператор << имеет более высокий приоритет, чем <, так что это обрабатывается как

(cout << a) < " "; 

Вы на самом деле не сравнивая строку с целым числом. Вместо этого вы сравниваете возвращаемое значение ostream::operator<<, которое равно std::cout, в строковый литерал. Это не законно (в том смысле, который имеет неопределенный результат, и это не имеет смысла) либо, clang предупреждает:

warning: result of comparison against a string literal is unspecified 

Причина, почему он компилирует в том, что вплоть до C++ 11, std::ostream может неявно преобразуется в void *. Кроме того, строковый литерал типа const char[2] распадается на указатель типа const char *. Таким образом, оператор < теперь принимает два указателя, что разрешено, хотя его результат не указан, поскольку два указателя не указывают на один и тот же объект.

+1

Unspecified! = Незаконно. – jrok

+0

@jrok Я не рассматривал бы что-либо юридическое, которое испускает предупреждение компилятора, или что-то, что * не делает то, что думает, что оно делает * (примерно). –

+0

быстрый вопрос: действительно ли перегрузка влияет на приоритет оператора? (<< перегружен сверху) – winterlight

1

Это вниз к оператору precedence

т.е.

Линия приравнивает к (cout << a) < " "; - Поэтому <" " ничего не делает!

EDIT

Этот бит возвращает объект (cout << a) возвращает объект типа ostream, где он не имеет перегруженный оператор <, так как компилятор отказывается (C++ 11) или царапает его голову AMD имеет bash для целочисленного оператора (т. е. указатели и т. д.).

+2

Возможно, стоит объяснить, почему * это * сравнение работает. –

+0

@ KonradRudolph Или, скорее, почему это * не * работа. –

+0

@ H2CO3 Или, вернее, почему он больше не работает * в C++ 11 *. До C++ 11 он работает отлично. –

3

Фактически, так как это (cout << a) < " ", мы сравниваем ostream с " ". Класс ostream имеет оператора для его преобразования в void *. Вы можете сравнить void * с const char * без приведения в действие, поэтому компилятор с радостью делает это, а затем понимая, что вы не используете результат сравнения, и выдает предупреждение.

Одна из этих причудливых вещей в C++.

+0

Но @Ed Heal сказал, что объект 'ostream' не имеет перегруженного' <'. Я что-то упустил? – winterlight

+1

Правильно, это не так. Таким образом, компилятор находит преобразование в тип, который можно сравнить - в этом случае «operator (void *)». –

+0

'ostream' * имел * оператор void *()', но больше не работает. –

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