提问人:gozag 提问时间:5/19/2023 最后编辑:InSyncgozag 更新时间:5/24/2023 访问量:3349
C/C++ 警告或禁止文字字符串连接
C/C++ warn or prohibit literal string concatenation
问:
有没有办法警告或禁止文字字符串连接,例如:
const char *a = "foo" " bar";
我花了几个小时在一个大型静态数组中发现了一个错误,该错误具有
const char * a[] = {"foo" "bar"};
而不是
const char * a[] = {"foo", "bar"};
答:
没有。字符串文字连接是 C/C++ 语法中不可或缺的一部分,并且有许多用例。因此,需要付出某种努力,这可能会破坏抓住失误的目标。
但是,字符串连接非常严格地适用于两个字符串文本,它们之间只有空格,因此中断空格将导致错误。例如,在这种情况下,你可以写成:
const *char[] = {("foo") ("bar")}; // Error
这将导致错误,而预期的语句不会:
const *char[] = {("foo"), ("bar")}; // OK
因此,简而言之,您无法通过某种方式明确地告诉编译器可以连接两个字符串文本,并在所有其他情况下使其失败,因此您必须明确告诉编译器何时字符串文本可能不连接。
评论
,
const char*
char*
const char*
Clang 有一个警告 -Wstring-concatenation,它被明确设计用于捕获此类错误:
warning: suspicious concatenation of string literals in an array initialization; did you mean to separate the elements with a comma? [-Wstring-concatenation]
char const *a[] = { "ok", "foo" "bar", "ok"};
^
,
这并不完全适用于您展示的玩具示例,因为您需要有多个初始值设定项,并且只在几个地方遗漏逗号,即:
// no warning
char const *b[] = {"foo" "bar"};
// no warning
char const *c[] = {"ok", "foo" "bar"};
// no warning
char const *d[] = {"foo" "bar", "ok"};
但是,当你在一个数组中有大量的初始值设定项,并且只在几个地方犯了一个错别字时,这似乎是理想的。
这是一个演示。
GCC 似乎没有等效的警告,但有人请求添加它。
请注意,这仅适用于数组初始化。你的例子
const char *x = "foo" " bar";
不会被此警告(或我知道的任何其他警告)检测到。
另请注意,启用此警告可能会产生大量误报,但在尝试捕获 bug 时可以谨慎使用它。
评论
-Wtraditional
下面的任何一个宏都不可能意外地连接两个字符串。
CPP(C 预处理器)宏通常很棒。在元素列表的末尾使用尾随逗号也是合法的。
你可以做这样的事情:
#define STRINGCOMMA(a) a,
const char *x[] = {
STRINGCOMMA("foo")
STRINGCOMMA("bar")
};
甚至:
#define QUOTESTRINGCOMMA(a) #a,
const char *x[] = {
QUOTESTRINGCOMMA(foo)
QUOTESTRINGCOMMA(bar)};
逗号是为您添加的,您自己不小心这样做是违法的。
如果您有兴趣,也可以进一步利用这个概念,以允许创建具有相同参数但处理方式不同的并行列表:
#define VARLIST \
DO(foo) \
DO(bar)
#define DO(a) #a,
const char *x[] = {
VARLIST
};
#undef DO
如果要从同一名称列表创建枚举列表和字符串列表,这将非常有用。
我花了几个小时在一个大的静态数组中发现了一个错误......
好吧,你可以这样做:
char const * a [] =
{ "foo"
, "bar"
, "baz"
, "asdf"
, "ghjk"
};
评论
下一个:swig 忽略未知的基类
评论
"
grep '"\s*$'
string3
“) 之后忘记了,
以及 为什么允许串联字符串文字?(2010 年。“我最近被一个微妙的虫子咬了......我忘记了,
两个
之后)