为什么允许字符串字面量的连接?
我最近遇到了一个很棘手的错误。
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 个回答
这是一个很棒的功能,它可以让你把预处理器字符串和你的字符串结合在一起。
// 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));
当然,这是一种让你的代码看起来更好的简单方法:
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
我看到有很多关于 C 和 C++ 的回答,但没有人真正解释 为什么 或者这个功能背后的原因是什么。在 C++ 中,这个功能源自 C99,我们可以通过查看 国际标准—编程语言—C 的理由 中的 6.4.5
节 字符串字面量 来找到这个功能的原因。里面提到(强调是我的):
一个字符串可以通过使用反斜杠和换行符来跨多行书写,但这要求字符串的延续部分必须从下一行的第一个位置开始。为了允许更灵活的排版,并解决一些预处理的问题(见 §6.10.3),C89委员会引入了字符串字面量的连接。两个连续的字符串字面量会直接拼接在一起,中间没有空字符,从而形成一个组合的字符串字面量。这个对C语言的补充允许程序员在不使用反斜杠和换行符的情况下,将字符串字面量扩展到物理行的末尾,这样就不会破坏程序的缩进格式。没有引入明确的连接操作符,因为连接是一个词法结构,而不是运行时操作。
Python 似乎也有同样的原因,这样可以减少使用丑陋的 \
来继续长字符串字面量的需求。这个内容在 Python语言参考 的 2.4.2 字符串字面量连接 中有介绍。