为什么 const char[] 总是转换为 const char*?

Why does const char[] get converted to const char* all the time?

因此,我知道字符串文字的类型为 const char[N]。而且我还知道,如果我们在某些函数中获得 const char[] 参数,编译器会自动将其转换为 const char*

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

这里有几个例子:

void f(int x) {}
int main()
{
    f("Hello");
    return 0;
}

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

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

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

编辑:我正在使用 GNU GCC。

Why does const char[] get converted to const char* all the time?

一般来说,因为还有一个规则和你提到的函数参数调整密切相关:

[conv.array] Array-to-pointer conversion

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The temporary materialization conversion ([conv.rval]) is applied. The result is a pointer to the first element of the array.

[basic.lval] Value category

Whenever a glvalue appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue.

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

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

In terminal: terminate called after throwing an instance of 'char const*'

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

[expr.throw] Throwing an exception

Evaluating a throw-expression with an operand throws an exception; the type of the exception object is determined by removing any top-level cv-qualifiers from the static type of the operand and adjusting the type from “array of T” or function type T to “pointer to T”.

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


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

[dcl.fct] Functions

... After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”

P.S。异常处理器也有类似的调整规则:

[except.handle] Handling an exception

A handler of type “array of T” or function type T is adjusted to be of type “pointer to T”.