为什么允许字符串字面量的连接?

14 投票
10 回答
3945 浏览
提问于 2025-04-15 20:46

我最近遇到了一个很棘手的错误。

char ** int2str = {
   "zero", // 0
   "one",  // 1
   "two"   // 2
   "three",// 3
   nullptr };

assert( int2str[1] == std::string("one") ); // passes
assert( int2str[2] == std::string("two") ); // fails

如果你有超强的代码审查能力,你会发现我在 "two" 后面忘记加了一个 ,

经过一番努力才找到这个错误,我不禁要问:为什么会有人想要这样的行为呢?

我能理解这在宏编程中可能会有用,但为什么在像Python这样的现代语言中会把它当作一个“特性”呢?

你有没有在实际代码中使用过字符串字面量拼接?

10 个回答

17

这是一个很棒的功能,它可以让你把预处理器字符串和你的字符串结合在一起。

// Here we define the correct printf modifier for time_t
#ifdef TIME_T_LONG
    #define TIME_T_MOD "l"
#elif defined(TIME_T_LONG_LONG)
    #define TIME_T_MOD "ll"
#else
    #define TIME_T_MOD ""
#endif

// And he we merge the modifier into the rest of our format string
printf("time is %" TIME_T_MOD "u\n", time(0));
23

当然,这是一种让你的代码看起来更好的简单方法:

char *someGlobalString = "very long "
                         "so broken "
                         "onto multiple "
                         "lines";

不过,最好的理由是处理一些奇怪的printf格式,比如强制类型转换:

uint64_t num = 5;
printf("Here is a number:  %"PRIX64", what do you think of that?", num);

有很多这样的格式定义,如果你对数据类型的大小有要求,它们会很有用。你可以在这个链接里查看所有的格式。这里有几个例子:

PRIo8 PRIoLEAST16 PRIoFAST32 PRIoMAX PRIoPTR
5

我看到有很多关于 CC++ 的回答,但没有人真正解释 为什么 或者这个功能背后的原因是什么。在 C++ 中,这个功能源自 C99,我们可以通过查看 国际标准—编程语言—C 的理由 中的 6.4.5字符串字面量 来找到这个功能的原因。里面提到(强调是我的):

一个字符串可以通过使用反斜杠和换行符来跨多行书写,但这要求字符串的延续部分必须从下一行的第一个位置开始。为了允许更灵活的排版,并解决一些预处理的问题(见 §6.10.3),C89委员会引入了字符串字面量的连接。两个连续的字符串字面量会直接拼接在一起,中间没有空字符,从而形成一个组合的字符串字面量。这个对C语言的补充允许程序员在不使用反斜杠和换行符的情况下,将字符串字面量扩展到物理行的末尾,这样就不会破坏程序的缩进格式。没有引入明确的连接操作符,因为连接是一个词法结构,而不是运行时操作。

Python 似乎也有同样的原因,这样可以减少使用丑陋的 \ 来继续长字符串字面量的需求。这个内容在 Python语言参考2.4.2 字符串字面量连接 中有介绍。

撰写回答