如何在我的程序中找到"const char*+ int"表达式

vz0*_*vz0 12 c c++ migration vb6-migration

我正在进行源代码迁移,转换器程序没有使用整数转换嵌入字符串的串联.现在我有很多代码用这种表达式:

f("some text" + i);
Run Code Online (Sandbox Code Playgroud)

由于C/C++将其解释为数组下标,f将收到"some text",或"ome text",或"me text"...

我的源语言将字符串的串联转换为int作为字符串连接.现在我需要逐行浏览源代码并手动将前一个表达式更改为:

f("some text" + std::to_string(i));
Run Code Online (Sandbox Code Playgroud)

转换程序设法将本地" String"变量转换为" std::string",从而产生表达式:

std::string some_str = ...;
int i = ...;

f(some_str + i);
Run Code Online (Sandbox Code Playgroud)

这些很容易修复,因为有了这样的表达式,C++编译器会输出错误.

是否有任何工具可以在源代码上自动找到这样的表达式?

esn*_*der 8

简单!只需更换所有+-&:

find . -name '*.cpp' -print0 | xargs -0 sed -i '' 's/+/-\&/g'
Run Code Online (Sandbox Code Playgroud)


在尝试编译项目时,您会在其他错误之间看到类似这样的内容:

foo.cpp:9:16: error: 'const char *' and 'int *' are not pointers to compatible types
    return f(s -& i);
             ~ ^~~~
Run Code Online (Sandbox Code Playgroud)

(我正在使用clang,但其他编译器应该发出类似的错误)


所以你只需要过滤编译器输出以仅保留那些错误:

clang++ foo.cpp 2>&1 | grep -F "error: 'const char *' and 'int *' are not pointers to compatible types"
Run Code Online (Sandbox Code Playgroud)

你得到:

foo.cpp:9:16: error: 'const char *' and 'int *' are not pointers to compatible types
foo.cpp:18:10: error: 'const char *' and 'int *' are not pointers to compatible types
Run Code Online (Sandbox Code Playgroud)


Alp*_*per 7

您可以尝试使用flint,一种在Facebook上开发和使用的C++开源lint程序.它具有列入黑名单的令牌序列功能(checkBlacklistedSequences).您可以将标记序列添加到checkBlacklistedSequences函数中并flint进行报告.

checkBlacklistedSequences功能上,我添加了序列string_literal + number

BlacklistEntry([tk!"string_literal", tk!"+", tk!"number"],
               "string_literal + number problem!\n",
                true),
Run Code Online (Sandbox Code Playgroud)

然后编译和测试

$ cat -n test.cpp
 1  #include <iostream>
 2  #include <string>
 3  
 4  using namespace std;
 5  
 6  void f(string str)
 7  {
 8      cout << str << endl;
 9  }
10  
11  int main(int argc, char *argv[])
12  {
13      f("Hello World" + 2);
14  
15      f("Hello World" + std::to_string(2));
16  
17      f("Hello World" + 2);
18  
19      return 0;
20  }

$ ./flint test.cpp 
test.cpp(13): Warning: string_literal + number problem!
test.cpp(17): Warning: string_literal + number problem!
Run Code Online (Sandbox Code Playgroud)

flint 有两个版本(用C++开发的旧版本和D语言的新版本),我在D版本中进行了更改.


vz0*_*vz0 2

我找到了一个非常简单的方法来检测这个问题。正则表达式和 lint 都不会匹配更复杂的表达式,如下所示:

f("Hello " + g(i));
Run Code Online (Sandbox Code Playgroud)

我需要的是以某种方式进行类型推断,所以我让编译器来完成它。使用 anstd::string而不是文字字符串会引发错误,因此我编写了一个简单的源代码转换器来将所有字符串文字转换为包装std::string版本,如下所示:

f(std::string("Hello ") + g(i));
Run Code Online (Sandbox Code Playgroud)

然后,重新编译项目后,我会看到所有错误。源代码在GitHub上,共48行Python代码:

https://gist.github.com/alejolp/3a700e1730e0328c68de