1

在 zflog 库中我看到了这段代码

static char* lvl_char(const int lvl)
{
    switch (lvl)
    {
    case ZF_LOG_VERBOSE:
        return "VERBOSE\0";
    case ZF_LOG_DEBUG:
        return "DEBUG\0";
    case ZF_LOG_INFO:
        return "INFO\0";
    case ZF_LOG_WARN:
        return "WARN\0";
    case ZF_LOG_ERROR:
        return "ERROR\0";
    case ZF_LOG_FATAL:
        return "FATAL\0";
    default:
        ASSERT_UNREACHABLE("Bad log level");
        return "?\0";
    }
}

这对我来说似乎很奇怪。我们真的可以从静态函数返回一个本地 c 字符串吗?

4

4 回答 4

7

函数的链接(这里是静态的)根本不重要。也不返回“字符串”;相反,返回的是一个指向 char 的指针。返回指向字符串文字的第一个字符的指针是完全合法的 - 字符串文字保证在程序的整个持续时间内都存在。C11 6.4.5p6声明此处使用的字符串文字用于初始化 *“一个 [anonymous]静态存储持续时间和长度刚好足以包含序列的数组”。静态存储持续时间意味着它的“生命周期是程序的整个执行过程,并且它的存储值仅在程序启动之前初始化一次”。( C11 6.2.4p3 )。


看起来很奇怪的是\0字符串文字的末尾,因为文字字符串总是以 0 结尾,所以本质上"VERBOSE\0"只会以 2 个零字节而不是通常的一个字节结尾;strlenfor 该字符串将返回7,就像它返回 for 一样"VERBOSE",依此类推。

于 2017-05-03T06:14:45.030 回答
5

你错了,返回的指针不是指向 local char array,而是指向 a string literal,即static进程。

来自c 标准

6.4.5 字符串文字

语义学

在翻译阶段 7,一个字节或值为零的代码被附加到每个由一个或多个字符串文字产生的多字节字符序列。78)然后使用多字节字符序列来初始化一个静态存储持续时间和长度刚好足以包含序列。 [...]

重点矿

于 2017-05-03T06:14:03.627 回答
3
于 2017-05-03T06:38:23.173 回答
2
  • 静态 c 函数可以返回本地 char 数组吗?不,这会导致未定义的行为。
  • 您的代码是否返回本地字符数组?不,它返回一个指向字符串字面量的指针,该字面量位于只读内存中。这个内存不是本地的。
  • 您可以从任何函数返回指向字符串文字的指针吗?是的。
  • 常规函数和内部链接函数之间有区别static吗?不。
于 2017-05-03T06:43:28.897 回答