简体   繁体   English

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

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

So, I'm aware that a string literal has a type of const char[N] .所以,我知道字符串文字的类型为const char[N] And I'm also aware that if we got a const char[] parameter in some function, compiler automatically converts it to const char* .而且我也知道,如果我们在某个const char[]得到一个const char[]参数,编译器会自动将其转换为const char*

But why do I always get compiler error messages saying that a string literal has a type of const char* ?但是为什么我总是收到编译器错误消息,说字符串文字的类型是const char*

Here's a few examples:下面是几个例子:

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

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

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

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

EDIT: I'm using GNU GCC.编辑:我正在使用 GNU GCC。

Why does const char[] get converted to const char* all the time?为什么 const char[] 一直被转换为 const char*?

Generally, because there is another rule closely related to the function parameter adjustment that you mentioned:一般来说,因为你提到的函数参数调整还有另外一个规律:

[conv.array] Array-to-pointer conversion [conv.array] 数组到指针的转换

An lvalue or rvalue of type “array of NT” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. “NT 数组”或“T 的未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。 The temporary materialization conversion ([conv.rval]) is applied.应用了临时物化转换 ([conv.rval])。 The result is a pointer to the first element of the array.结果是指向数组第一个元素的指针。

[basic.lval] Value category [basic.lval] 值类别

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

Colloquially, this implicit conversion is called pointer decaying .通俗地说,这种隐式转换称为指针衰减

The error message appears to describe an attempt to convert this intermediary result of lvalue-to-rvalue conversion to the parameter type.该错误消息似乎描述了尝试将左值到右值转换的此中间结果转换为参数类型的尝试。

In terminal: terminate called after throwing an instance of 'char const*'在终端中:在抛出 'char const*' 实例后调用终止

In this particular case of exception throwing, there is a specific rule, which is essentially same as pointer decaying, but in context of a throw:在异常抛出的这种特殊情况下,有一个特定的规则,它本质上与指针衰减相同,但在抛出的上下文中:

[expr.throw] Throwing an exception [expr.throw] 抛出异常

Evaluating a throw-expression with an operand throws an exception;使用操作数计算 throw 表达式会引发异常; 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” .异常对象的类型是通过从操作数的静态类型中删除任何顶级 cv 限定符并将类型从“T 数组”或函数类型 T 调整为“指向 T 的指针”来确定的

So, the adjusted type of the exception object is in fact const char* , and it is this uncaught object that the compiler generated message describes.因此,异常对象的调整类型实际上是const char* ,编译器生成的消息描述的正是这个未捕获的对象。


For completeness, here is the parameter adjustment rule that you knew:为了完整起见,这是您知道的参数调整规则:

[dcl.fct] Functions [dcl.fct] 函数

... 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” ... 确定每个参数的类型后,任何类型为“T 数组”或函数类型为 T 的参数都被调整为“指向 T 的指针”

PS there is also an analogous adjustment rule for exception handlers: PS还有一个类似的异常处理程序调整规则:

[except.handle] Handling an exception [except.handle] 处理异常

A handler of type “array of T” or function type T is adjusted to be of type “pointer to T”.类型为“T 数组”或函数类型 T 的处理程序被调整为“指向 T 的指针”类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 boost::variant - 为什么“const char*”转换为“bool”? - boost::variant - why is “const char*” converted to “bool”? 为什么从“ const int”到“ int”的转换有效,但从“ const char []”到“ char *”的转换却无效 - Why “const int” to “int” conversion works but “const char[]” to “char *” does not 为什么此函数将&#39;const char *&#39;强制转换为&#39;void * const&#39;而不是&#39;const void *&#39; - Why does this function cast 'const char*' to 'void* const' and not 'const void*' (const char *)++还是(const char)++? - (const char*)++ or (const char)++? 为什么 const char* 到 const char 转换时出错? - Why error on const char* to const char conversion? 为什么不能将&#39;const char *&#39;左值绑定到&#39;const char * const &amp;&amp;? - Why cannot bind ‘const char*’ lvalue to ‘const char* const&&? 为什么 const char* 隐式转换为 bool 而不是 std::string? - Why const char* implicitly converted to bool rather than std::string? const char *和char const * - 它们是一样的吗? - const char* and char const* - are they the same? 为什么const char * const&=“hello”编译? - Why can const char* const & = “hello” compile? 为什么 const int 需要 extern 而 const char* 不需要 - Why is extern required for const int but not for const char*
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM