我们刚刚发现我们的同事认为他可以向 std::string 添加一个整数,并在他的代码中到处使用这样的操作。
我们没有看到此操作的任何编译器错误,我不明白为什么:没有operator+ (const string& lhs, int rhs);
. int 是否被默默地转换为 char?(使用 gcc Red Hat 4.1.2 和 -Wall 开关编译)。
而且,最重要的是,我们如何找到将 int 添加到 std::string 的所有行?
我们刚刚发现我们的同事认为他可以向 std::string 添加一个整数,并在他的代码中到处使用这样的操作。
我们没有看到此操作的任何编译器错误,我不明白为什么:没有operator+ (const string& lhs, int rhs);
. int 是否被默默地转换为 char?(使用 gcc Red Hat 4.1.2 和 -Wall 开关编译)。
而且,最重要的是,我们如何找到将 int 添加到 std::string 的所有行?
当您的同事仅使用整数文字时,它们将被转换为char
- 但是,如果整数的值太大,您将看到警告。被调用的运算符是
std::string operator+(const std::string &s, char c); // actually it's basic_string<> with some CharT...
或+=
变体;)
关于如何找到所有电话。您可以为所有运算符的出现编译(无内联)所有代码,objdump
并在过滤后的地址上使用:grep
addr2line
$ cat string-plus.cpp
#include <string>
int main()
{
std::string a = "moof ";
a += 192371;
}
$ g++ -g string-plus.cpp
string-plus.cpp: In function ‘int main()’:
string-plus.cpp:5: warning: overflow in implicit constant conversion
$ objdump -Cd a.out | \
grep 'call.*std::string::operator+=(char)@plt' | \
tr -d ' ' | \
cut -d: -f1 | \
xargs addr2line -Cfe string-plus
main
??:0
然而,这并没有给我行号......至少呼叫站点在那里;)
该-C
开关启用 c++ 名称解构。这也可以使用 binutls 手动完成c++filt
。
有趣的是,有一个operator+
forstring
和的定义char
,但只有当使用operator+=
整数文字转换为 时char
,我必须传递一个char
文字(或值)operator+
才能使用。
要查找您的运营商的错位名称:
$ cat a.cpp
#include <string>
int main()
{
std::string a = "moof ";
a = a + char(1);
}
$ g++ a.cpp
$ objdump -t a.out | c++filt | grep operator+ | cut -d ' ' -f1
08048780
$ objdump -t a.out | grep 0804878
08048780 w F .text 00000067 _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S3_
最后一个是您要搜索的名称 - 可用于 grep w/o name demangling。
我真的不知道更好的方法来做到这一点......:/