C++ 为什么是';int x=+&引用;“福”';类型错误,但不是语法错误?
我尝试的所有编译器都正确地拒绝了代码C++ 为什么是';int x=+&引用;“福”';类型错误,但不是语法错误?,c++,C++,我尝试的所有编译器都正确地拒绝了代码 int main() { int x = "foo"; } 类型错误:const char[4]无法转换为int。为什么相同的编译器(包括)会为 int main() { int x = + "foo"; } 而不是(如我所想)由于+符号而导致的语法错误?我的第一个想法是const char[4]衰减为指针,指针又被视为整数值,因此+表示“正”。不过似乎有点牵强,我希望看到const char*出现在错误消息中。语法不涉及类型系统意义上的类型(i
int main() {
int x = "foo";
}
类型错误:const char[4]
无法转换为int
。为什么相同的编译器(包括)会为
int main() {
int x = + "foo";
}
而不是(如我所想)由于
+
符号而导致的语法错误?我的第一个想法是const char[4]
衰减为指针,指针又被视为整数值,因此+
表示“正”。不过似乎有点牵强,我希望看到const char*
出现在错误消息中。语法不涉及类型系统意义上的类型(int、chars和指针),只涉及语法意义上的关键字、运算符和表达式。在C++语法中,+“foo”
是一个有效的表达式
您认为字符串常量会衰减为指针,+
是指针上的不可操作的想法是正确的,下面的程序甚至会编译并运行:
#include <iostream>
int main()
{
const char *message = +"Hello!\n";
std::cout << message;
}
一元<代码> +/>代码适用于指针,它只返回类型的值,不执行指针的积分提升,因此结果是指针,不是整数类型,从草案C++标准部分<代码> 5.3.1 < /代码>一元运算符: 一元+运算符的操作数应具有算术、无范围 枚举或指针类型,结果是 论点整数升级是对整数或枚举执行的 操作数。结果的类型是提升的操作数的类型 字符串文字是常量字符的数组,来自
2.14.5
string文字:
[…]窄字符串文字的类型为“n常量字符数组”[…]
在此上下文中,它将衰减为指针。一元
+
运算符可应用于指针类型:
C++11 5.3.1[expr.unary.op]/7:一元+运算符的操作数应具有算术、无范围枚举或指针类型,结果为参数值
因此,文本数组被转换为const char*
,并将运算符应用于该指针,然后无法像第一个示例中那样将指针分配给int
为什么“intx=+”foo“;”类型错误,但不是语法错误
因为没有语法错误。有一个语义错误
解析语句后,编译器确定是否可以进行此类初始化。事实上,从句法上看,该语句如下所示
int x = + ( expression );
从句法上来说,这句话是正确的。此外,一元加号可以应用于指针 将
x
更改为const char*
会编译,因此加号显然不是语法错误。我很想知道为什么。作为旁注,在我的ideone中运行时,您链接的错误是,const char*
不能转换为int
,而不是const char[4]
。我不知怎的假设,+
是一元前缀运算符,只能在数字文本之前(即,在解析时容易检测到的东西)。我没想到它可以出现在任何表达式之前@FrerichRaabe您甚至可以重载它,请参见更新的答案:)有趣的事实包括,由于负号或正号是通用运算符,而不是文字语法的一部分,用C++实现基于两个整数的互补表示,不可能把一个带符号类型的最负值表示为一个负文字。例如,对于16位int
,表达式-32768
相当于0-32768
,其中包含超出范围的正值32768:invalid。这与@cheers和hth.-Alf建议的不完全一样:对于16位int
,表达式-32768
是一元-
运算符对十进制常量32768
的应用32768
不能放入int
,因此它具有类型long
,对long
求反将产生另一个long
<代码>-32768因此始终具有预期值,但不总是预期类型。之所以产生这个问题是表达式<代码> -922337203685477580 < /C>,因为<代码> 922337203685477580 < /C>可能不适合任何有符号整数类型。语法实际上涉及C++中的类型…有趣的是,使用Visual Studio 2012编译我的测试程序时会产生一条错误消息,即const char[4]
无法转换为int
,即指针衰减的事实在错误消息中不再可见(Ideone.com似乎使用了使用const char*
的编译)。
int x = + ( expression );