我正在用 C++ 为 Web 服务后端编写一个巨大的代码库,我的前端是用 Javascript 编写的,所以我倾向于编写一些前端代码,然后再返回到 C++ 代码,我更愿意在某个地方写下以下犯罪代码:
container['myKey']
,这通常会在某个地方变成崩溃,我使用缓存编译进行了热重载,这意味着如果我没有捕捉到编译器在第一次发生时为多字符字符串抛出的警告,我将看不到它在下一次编译中(因为该单元可能不会重新编译)。
这是一个非常愚蠢的错误,它会给我的软件带来随机崩溃,有时我需要几个小时才能找到罪魁祸首并修复它。出于某种原因,编译器对多字符字符串长于 4 个字符 的警告不能在 g++ 中变成错误(它没有警告代码,就像其他警告一样。)。这意味着我只剩下编写某种 linter 来放入我的 CI/CD 中,以便在找到多字符文字时导致错误。
所以我的想法是写一个小的 bash 脚本来检查我所有的 .cpp 文件是否有任何多字符文字,如果发现任何错误则返回错误。
我试着写一个正则表达式来捕捉那些,但我失败了,如果你,一个正则表达式魔术师,能帮我写一个正则表达式来捕捉“像这样的东西”,而不是“像这样的东西”,我会很高兴(调用 query("SELECT * FROM data WHERE data LIKE ('potato')") 应该是有效的。
提前致谢。
编辑:附加信息: 按照评论中提出的解决方案,我尝试了-Werror=multichar,我发现了一些非常奇怪的东西。 它只在少数情况下有效:
g++ -o obj/src/main.ocpp -c src/main.cpp -fno-trapping-math -Werror=multichar -O3 -std=c++17 -D_FORCE_INLINES -I./src/include -I/usr/include/mysql
src/main.cpp:52:11: error: multi-character character constant [-Werror=multichar]
52 | langAll['test'] = true;
因为如果单引号内的字符太多,警告会改变:
g++ -o obj/src/main.ocpp -c src/main.cpp -fno-trapping-math -Werror=multichar -O3 -std=c++17 -D_FORCE_INLINES -I./src/include -I/usr/include/mysql
src/main.cpp:52:11: warning: character constant too long for its type
52 | langAll['testtttttt'] = true;
我发现 GCC 部分代码脱口而出这个警告: https://github.com/gcc-mirror/gcc/blob/master/libcpp/charset.cc
if (type == CPP_UTF8CHAR)
max_chars = 1;
if (i > max_chars)
{
i = max_chars;
cpp_error (pfile, type == CPP_UTF8CHAR ? CPP_DL_ERROR : CPP_DL_WARNING,
"character constant too long for its type");
}
else if (i > 1 && CPP_OPTION (pfile, warn_multichar))
cpp_warning (pfile, CPP_W_MULTICHAR, "multi-character character constant");
不确定如何打开这个:
CPP_DL_WARNING,"character constant too long for its type");
虽然出错了。
在与 chatgpt 交谈后,它建议: -Woverlength-strings -Werror=overlength-strings ,但将警告变成错误也不起作用。
由于没有人帮忙,我自己做了一个解决方案来解决这个问题(有点 linter): https://github.com/Brasilibr/cppmultilinecharchecker 这是一个 cpp 程序,您将一个文件夹作为第一个参数传递给它,它将验证该文件夹下的每个文件(以及递归的所有文件夹)。它将检查任何超过 4 个字符的多字节字符,如果找到则返回 0,如果所有文件都正常则返回 1。 您可以使用 run.sh 在任何基于 Debian 的 linux 或 ubuntu WSL 中运行它。