我试过的所有编译器都正确拒绝了代码
int main() {
int x = "foo";
}
类型错误:const char[4]
无法转换为int
。为什么相同的编译器(包括Ideone.com)给出了相同的错误
int main() {
int x = + "foo";
}
而不是(我认为)+
符号的语法错误?我的第一个想法是const char[4]
衰减到一个指针,而指针又被视为一个整数值,因此+
表示"正面"。虽然看起来有点牵强,但我希望看到const char*
出现在错误消息中。
答案 0 :(得分:34)
语法不涉及类型系统意义上的类型(整数和字符和指针),只涉及关键字,运算符,表达式的句法意义上的类型。在C ++语法中,+
是一个可以在表达式之前的一元前缀运算符。 "foo"
是一个表达。因此,就解析器而言,+"foo"
是一个有效的表达式。
您认为字符串常量衰减为指针并且+
是指针上的无操作是正确的,并且以下程序甚至编译并运行:
#include <iostream>
int main()
{
const char *message = +"Hello!\n";
std::cout << message;
}
......但这无关紧要。您所看到的是类型错误,而不是语法错误。
编辑或许更有说服力的是你可以重载一元+
:
#include <iostream>
struct SomeType {
const char *operator+() const
{
return "Hello, world!\n";
}
};
int main()
{
SomeType x;
std::cout << +x;
}
答案 1 :(得分:9)
一元+
适用于指针,它只返回类型的值,并且不对指针执行整数提升,因此结果是指针不是整数类型,来自草案C ++标准部分{{1} } 一元运算符:
一元+运算符的操作数应具有算术,无范围 枚举,或指针类型,结果是值的 论点。整体推广是针对整体或枚举进行的 操作数。结果的类型是提升的操作数的类型。
字符串文字是一个const char数组,来自5.3.1
字符串文字:
[...]窄字符串文字的类型为“n const char数组”,[...]
将在此上下文中衰减为指针。
答案 2 :(得分:7)
一元+
运算符可以应用于指针类型:
C ++ 11 5.3.1 [expr.unary.op] / 7:一元+运算符的操作数应具有算术,无范围枚举或指针类型,结果为值论证。
因此,文本数组转换为const char *
,并且操作符应用于该指针,然后无法将指针指定给int
,就像在第一个示例中一样。
答案 3 :(得分:4)
为什么'int x = +“foo”;'类型错误但不是语法错误?
因为没有语法错误。存在语义错误。
在解析语句之后,编译器确定这种初始化是否可行。实际上语法上看起来像
int x = + ( expression );
语法上这个陈述是正确的。此外,一元加号可以应用于指针。