C/C ++警告或禁止文字弦串联

问题描述 投票:0回答:4

有一种方法来警告或禁止字面串联串联,例如:

const char *a = "foo" " bar";

我花了几个小时在一个大的静态阵列中找到一个错误

const char * a[] = {"foo" "bar"};

const char * a[] = {"foo", "bar"};
c++ c string warnings
4个回答
51
投票

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"};

但是,当您在数组中有大量的初始化器并且仅在几个地方制作错字时,这似乎是理想的。 thehere是一个

demo

. GCC似乎没有等效的警告,但是要添加

request

注意这仅适用于数组初始化。您的例子

const char *x = "foo" " bar";

不会被此警告(或我知道的其他任何其他警告)检测到。 还要注意,启用此警告可能会产生很多误报,但是您可以在尝试捕获错误时很少使用它。

真的。字符串文字串联是C/C ++语法中必不可少的一部分,并且具有许多用例。因此,需要进行某种努力,这可能会击败捕获失误的目标。

否则,字符串串联在两个彼此之间仅出现的两个字符串文字上非常严格起作用,仅在两者之间只有空白,因此打破空白将导致错误。例如,在这种情况下,您可以写:

const *char[] = {("foo") ("bar")}; // Error

18
投票
会导致错误,而预期的语句则不会:

const *char[] = {("foo"), ("bar")}; // OK

简而言之,简而言之,您无法明确地告诉编译器两个字符串文字可能是连接的,并且在所有其他情况下都失败了,因此您必须明确地告诉编译器,当字符串文字可能会

串联

下面的宏的含义使得不可能意外连接两个弦。

CPP(

C预处理程序)宏一般都很棒。 在元素列表的末尾进行尾随逗号也是合法的。 您可以做这样的事情:
#define STRINGCOMMA(a) a,

const char *x[] = {
    STRINGCOMMA("foo")
    STRINGCOMMA("bar")
};

或什至:

#define QUOTESTRINGCOMMA(a) #a, const char *x[] = { QUOTESTRINGCOMMA(foo) QUOTESTRINGCOMMA(bar)};

2
投票
逗号是为您添加的,您不小心自己做是非法的。

如果您有兴趣,也可以进一步采取此概念,以允许创建具有相同参数的并行列表,但处理不同的处理:

X宏观

#define VARLIST \ DO(foo) \ DO(bar) #define DO(a) #a, const char *x[] = { VARLIST }; #undef DO

如果您想从同一名称列表中创建枚举列表和字符串列表,这将很有用。

你有你的愿望;

./cxx/ClassSys.hxx:271:3: error: expected ')' [clang-diagnostic-error]
  271 |                 SUSUWU_ERROR(funcName + " {throw std::exception(\"" + ex.what() + "\");}");
      |                 ^
./cxx/Macros.hxx:340:84: note: expanded from macro 'SUSUWU_ERROR'
  340 | #       define SUSUWU_ERROR(x) {SUSUWU_PRINT(SUSUWU_SH_ERROR, x); SUSUWU_WARNING("`$0` " SUSUWU_EXPERIMENTAL_ISSUES);}
      |                                                                                          ^
./cxx/Macros.hxx:46:126: note: expanded from macro 'SUSUWU_EXPERIMENTAL_ISSUES'
   46 | #       define SUSUWU_EXPERIMENTAL_ISSUES "was built with `-DSUSUWU_EXPERIMENTAL`; if you experience issues, execute `git switch " SUSUWU_DEFAULT_BRANCH " && ./build.sh` (as possible fixup), [post the issue](https://github.com/SwuduSusuwu/SubStack/issues/new)"
      |                                                                                                                                    ^
note: expanded from macro 'SUSUWU_DEFAULT_BRANCH'
./cxx/ClassSys.hxx:271:3: note: to match this '('
  271 |                 SUSUWU_ERROR(funcName + " {throw std::exception(\"" + ex.what() + "\");}");
      |                 ^
./cxx/Macros.hxx:340:61: note: expanded from macro 'SUSUWU_ERROR'
  340 | #       define SUSUWU_ERROR(x) {SUSUWU_PRINT(SUSUWU_SH_ERROR, x); SUSUWU_WARNING("`$0` " SUSUWU_EXPERIMENTAL_ISSUES);}
      |                                                                   ^
./cxx/Macros.hxx:344:27: note: expanded from macro 'SUSUWU_WARNING'
  344 | #define SUSUWU_WARNING(x) SUSUWU_PRINT(SUSUWU_SH_WARNING, x)
      |                           ^
./cxx/Macros.hxx:337:33: note: expanded from macro 'SUSUWU_PRINT'
  337 | #       define SUSUWU_PRINT(LEVEL, x) SUSUWU_CERR(LEVEL, x

现在必须禁用

clang-tidy

,因为此代码是有效的,并且没有其他解决方案。

GLUE

宏和##请勿解决这个问题。

我花了几个小时在一个大静态阵列中找到一个错误...

,您可以做到这一点:

0
投票
char const * a [] = { "foo" , "bar" , "baz" , "asdf" , "ghjk" };


最新问题
© www.soinside.com 2019 - 2025. All rights reserved.