为什么 const char[] 一直被转换为 const char*?

ken*_*kar 2 c++ string-literals

所以,我知道字符串文字的类型为const char[N]. 而且我也知道,如果我们const char[]在某个函数中得到一个参数,编译器会自动将其转换为const char*.

但是为什么我总是收到编译器错误消息,说字符串文字的类型为const char*

下面是几个例子:

void f(int x) {}
int main()
{
    f("Hello");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误: invalid conversion from 'const char*' to 'int'

void f() {
    throw "Hello";
}
int main()
{
    try{ f(); } catch (int x) { std::cout << "No\n";}
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在终端: terminate called after throwing an instance of 'char const*'

编辑:我正在使用 GNU GCC。

eer*_*ika 5

为什么 const char[] 一直被转换为 const char*?

一般来说,因为你提到的函数参数调整还有另外一个规律:

[conv.array] 数组到指针的转换

“NT 数组”或“T 的未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。应用了临时物化转换 ([conv.rval])。结果是指向数组第一个元素的指针。

[basic.lval] 值类别

每当泛左值作为期望该操作数的纯右值的运算符的操作数出现时,就会应用左值到右值、数组到指针或函数到指针的标准转换来将表达式转换为纯右值。

通俗地说,这种隐式转换称为指针衰减

该错误消息似乎描述了尝试将左值到右值转换的此中间结果转换为参数类型的尝试。

在终端中:在抛出 'char const*' 实例后调用终止

在异常抛出的这种特殊情况下,有一个特定的规则,它本质上与指针衰减相同,但在抛出的上下文中:

[expr.throw] 抛出异常

使用操作数计算 throw 表达式会引发异常;异常对象的类型是通过从操作数的静态类型中删除任何顶级 cv 限定符并将类型从“T 数组”或函数类型 T 调整为“指向 T 的指针”来确定的

所以,异常对象的调整类型实际上const char*是,编译器生成的消息描述的就是这个未捕获的对象。


为了完整起见,这是您知道的参数调整规则:

[dcl.fct] 函数

... 确定每个参数的类型后,任何类型为“T 数组”或函数类型为 T 的参数都被调整为“指向 T 的指针”

PS还有一个类似的异常处理程序调整规则:

[except.handle] 处理异常

类型为“T 数组”或函数类型 T 的处理程序被调整为“指向 T 的指针”类型。