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

时间:2014-12-03 15:36:02

标签: c++

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

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

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

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

而不是(我认为)+符号的语法错误?我的第一个想法是const char[4]衰减到一个指针,而指针又被视为一个整数值,因此+表示"正面"。虽然看起来有点牵强,但我希望看到const char*出现在错误消息中。

4 个答案:

答案 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 );

语法上这个陈述是正确的。此外,一元加号可以应用于指针。