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

Fre*_*abe 21 c++

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

int main() {
  int x = "foo";
}
Run Code Online (Sandbox Code Playgroud)

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

int main() {
  int x = + "foo";
}
Run Code Online (Sandbox Code Playgroud)

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

Fre*_*Foo 34

语法不涉及类型系统意义上的类型(整数和字符和指针),只涉及关键字,运算符,表达式的语法意义上的类型.在C++语法中,+是一个可以在表达式之前的一元前缀运算符."foo"是一种表达.因此,+"foo"就解析器而言,是一个有效的表达式.

您认为字符串常量衰减为指针并且指针+上的无操作是正确的,并且以下程序甚至编译并运行:

#include <iostream>

int main()
{
    const char *message = +"Hello!\n";
    std::cout << message;
}
Run Code Online (Sandbox Code Playgroud)

......但这无关紧要.您所看到的是类型错误,而不是语法错误.

编辑也许更有说服力的事实是你可以重载一元+:

#include <iostream>

struct SomeType {
    const char *operator+() const
    {
        return "Hello, world!\n";
    }
};

int main()
{
    SomeType x;
    std::cout << +x;
}
Run Code Online (Sandbox Code Playgroud)

  • 有趣的事实包括由于负号或正号是一般运算符而不是文字语法的一部分,C++实现基于两个补码表示整数,因此不可能将带符号类型的最负值表示为负字面值.例如,对于16位`int`,表达式`-32768`相当于'0 - 32768`,它涉及超出范围的正值32768:无效. (3认同)
  • 它与@ Cheersandhth不完全相同.-Alf建议:对于16位`int`,表达式`-32768`是一元`-`运算符应用于十进制常量`32768`.`32768`不能适应`int`,因此它的类型为`long`,否定`long`会产生另一个`long`.因此,`-32768`始终具有预期值,并不总是预期的类型.什么*可以*产生该问题的是表达式`-9223372036854775808`,因为`9223372036854775808`可能不适合任何有符号整数类型. (3认同)

Sha*_*our 9

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

一元+运算符的操作数应具有算术,无范围枚举或指针类型,结果是参数的值.对整数或枚举操作数执行整体提升.结果的类型是提升的操作数的类型.

字符串文字是一个const char数组,来自2.14.5 String文字:

[...]一个狭窄的字符串文字具有类型"n const char数组",[...]

在这种情况下会衰减到指针.


Mik*_*our 7

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

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

因此const char *,在未能将指针指定给int第一个示例中之前,将文字数组转换为,并将运算符应用于该指针.