Почему "int x = +" foo "; ошибка типа, но не синтаксическая ошибка?
Все компиляторы Я попытался правильно отклонить код
int main() {
int x = "foo";
}
с ошибкой типа: const char[4]
не может быть преобразован в int
. Почему одни и те же компиляторы (включая Ideone.com) дают ту же ошибку для
int main() {
int x = + "foo";
}
вместо (как я думал) синтаксической ошибки из-за знака +
? Моя первая идея заключалась в том, что const char[4]
распадается на указатель, который, в свою очередь, рассматривается как целое значение, поэтому +
обозначает "положительный". Кажется немного надуманным, хотя, и я бы ожидал увидеть const char*
в сообщении об ошибке.
Ответы
Ответ 1
Синтаксис не включает типы в смысле системы типов (ints и символы и указатели), только типы в синтаксическом смысле ключевых слов, операторов, выражений. В синтаксисе С++ +
является унарным префиксным оператором, который может предшествовать выражению. "foo"
- выражение. Следовательно, +"foo"
является допустимым выражением в отношении парсера.
Ваша идея о том, что константа строки распадается на указатель, а +
- нет-op на указателях, верна, и следующая программа даже компилируется и запускается:
#include <iostream>
int main()
{
const char *message = +"Hello!\n";
std::cout << message;
}
... но это не имеет значения. То, что вы видите, это ошибка типа, а не синтаксическая ошибка.
EDIT Возможно, еще более убедительным является тот факт, что вы можете перегрузить унарный +
:
#include <iostream>
struct SomeType {
const char *operator+() const
{
return "Hello, world!\n";
}
};
int main()
{
SomeType x;
std::cout << +x;
}
Ответ 2
Унарный +
применяется к указателям, и он просто возвращает значение типа и не выполняет целые акции по указателям, поэтому результат является указателем, а не интегральным типом, из стандартного раздела проекта С++ 5.3.1
Унарные операторы:
Операнд унарного + оператора должен иметь арифметику, не облагаемую перечисление или тип указателя, и результатом является значение аргумент. Интегральное продвижение осуществляется по интегральной или перечисленной операнды. Тип результата - тип продвинутого операнда.
строковый литерал представляет собой массив из const char, from 2.14.5
Строковые литералы:
[...] Узкий строковый литерал имеет тип "массив из n const char", [...]
который будет распадаться на указатель в этом контексте.
Ответ 3
Унарный оператор +
может применяться к типам указателей:
С++ 11 5.3.1 [expr.unary.op]/7: операнд унарного + оператора должен иметь арифметическое, неперечисленное перечисление или тип указателя, и результатом будет значение аргумента.
Итак, литеральный массив преобразуется в const char *
, а оператор применяется к этому указателю, прежде чем не назначить указатель на int
так же, как в первом примере.
Ответ 4
Почему "int x = +" foo "; ошибка типа, но не синтаксическая ошибка?
Потому что синтаксическая ошибка отсутствует. Существует семантическая ошибка.
После синтаксического анализа оператора компилятор определяет, возможна ли такая инициализация. Фактически синтаксически утверждение выглядит как
int x = + ( expression );
Синтаксически это утверждение верно. Кроме того, унарный плюс может применяться к указателям.