def*_*ode 11 c c++ python d string-literals
我最近被一个微妙的bug咬了.
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".
经过相当大的努力找到这个bug我必须问为什么有人会想要这种行为?
我可以看到这对宏魔术有什么用处,但是为什么这是像python这样的现代语言中的"特征"?
您是否曾在生产代码中使用字符串文字串联?
Car*_*rum 22
当然,这是使代码看起来很好的简单方法:
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
R S*_*hko 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));
这可能有用的案例:
为前者提供更具体的例子:
// in version.h
#define MYPROG_NAME "FOO"
#define MYPROG_VERSION "0.1.2"
// in main.c
puts("Welcome to " MYPROG_NAME " version " MYPROG_VERSION ".");
我看到了几个C和C++答案,但没有一个真正回答为什么或这个功能的基本原理是什么?在C++中,此功能来自C99,我们可以通过转到国际标准\xe2\x80\x94Programming Languages\xe2\x80\x94C部分6.4.5 字符串文字的基本原理来找到此功能的基本原理,其中显示(重点是我的):
\n\n\n可以使用反斜杠\xe2\x80\x93newline 行延续来跨多行延续字符串,但这要求字符串的延续从下一行的第一个位置开始。为了允许更灵活的布局,并解决一些预处理问题(请参阅\xc2\xa76.10.3),C89 委员会引入了字符串文字连接。将一行中的两个字符串文字粘贴在一起,中间不包含空字符,以形成一个组合字符串文字。C 语言的这一新增功能允许程序员将字符串文字扩展到物理行末尾之外,而无需使用反斜杠\xe2\x80\x93newline 机制,从而破坏程序的缩进方案。未引入显式串联运算符,因为串联是词法构造而不是运行时操作。
\n
Python\\这似乎也有同样的原因,这减少了丑陋的继续长字符串文字的需要。\n The Python Language Reference的2.4.2 字符串文字连接部分对此进行了介绍。