为什么返回带有字符串文字的 const char * 的函数有效?

Why does a function returning const char * with string literals work?

我在 libcurl 中发现 code 看起来像:

const char *
curl_easy_strerror(CURLcode error)
{
  switch(error) {
  case CURLE_OK:
    return "No error";

  case CURLE_UNSUPPORTED_PROTOCOL:
    return "Unsupported protocol";
.....
}

据我所知,如果你想return一个指针,你需要确保指针指向的内存不会被改变或释放。为什么这个 libcurl 代码有效?

这些字符串文字在编译时放置在可执行文件的静态 read-only 部分中。它们与堆或堆栈分开。该函数只是返回一个指向这些字符串的指针。

参考

此实现因平台和编译器而异,但 C11 标准在第 6.4.5 节对此有一些相关要求。

In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.

所以我们知道它必须在编译时存储在静态位置。

If the program attempts to modify such an array, the behavior is undefined.

这告诉我们数据必须是 read-only。

编辑

有些人抱怨说这是不正确的,引用了特定的平台或架构。如上所述 这是特定于平台和编译器的

某些平台可能不支持 read-only 数据,但编译器几乎肯定会尝试阻止您修改它。由于行为是未定义的,目的是你永远不会这样做,所以对于所有意图和目的,数据是 read-only.

在问题的上下文中,这个答案是正确的。

根据 C 标准(6.4.5 字符串文字,第 6 段),字符串文字具有静态存储持续时间:

a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration […]

这意味着它们的内存,无论物理位置如何,都保证比函数 return 更有效,并且指向此内存的指针仍然有效。

因此,您正在 return 指向一个内存位置的指针,该内存位置保证有效,并且包含字符串文字给定的值。