为什么 'int x = + “foo”;' 是类型错误而不是语法错误

Why is 'int x = + "foo";' a type error but not a syntax error?

本文关键字:错误 类型 语法 int 为什么 foo      更新时间:2023-10-16

我尝试过的所有编译器都正确拒绝了代码

int main() {
  int x = "foo";
}

出现类型错误:const char[4]无法转换为 int 。为什么相同的编译器(包括 Ideone.com)给出相同的错误

int main() {
  int x = + "foo";
}

而不是(正如我所认为的那样)因为+符号而导致语法错误?我的第一个想法是,const char[4]衰减到指针,指针又被视为整数值,因此+表示"正"。不过似乎有点牵强,我希望看到const char*出现在错误消息中。

语法不

涉及类型系统意义上的类型(整数、字符和指针),只涉及语法意义上的关键字、运算符、表达式的类型。在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;
}

一元+适用于指针,它只返回类型的值,并且不对指针执行积分提升,因此结果是指针而不是整型类型,来自草稿C++标准部分5.3.1一元运算符

一元 + 运算符的操作数应具有算术,无作用域 枚举或指针类型,结果是 论点。对积分或枚举执行积分提升 操作。结果的类型是升级的操作数的类型。

字符串文字是常量字符的数组,来自2.14.5字符串文字

[...]窄字符串文字的类型为"n 常量字符数组",[...]

在这种情况下,它将衰减为指针。

一元+运算符可以应用于指针类型:

C++11 5.3.1 [expr.unary.op]/7:一元 + 运算符的操作数应具有算术、无作用域枚举或指针类型,结果是参数的值。

因此,文本数组被转换为 const char * ,并且运算符应用于该指针,然后未能将指针分配给int,就像第一个示例中一样。

为什么 'int x = + "foo";' 是类型错误而不是语法错误?

因为没有语法错误。存在语义错误。

解析语句后,编译器确定这种初始化是否可行。实际上,从语法上讲,该语句看起来像

int x = + ( expression );

从语法上讲,这种说法是正确的。此外,一元加号可以应用于指针。