Why does not std:string + int give compilation error?
We just found our colleague thought he can add an integer to std::string and 开发者_高级运维used such operation here and there in his code.
We don't see any compiler error for this operation and I don't understand why: there is no operator+ (const string& lhs, int rhs);
. Is int silently casted to char? (Compiling with gcc Red Hat 4.1.2 and -Wall switch).
And, most important, how do we find all the lines where int added to std::string?
When your colleague only used integer literals, these will be converted to char
- You will however see a warning if the value of the integer is too big. The operator that gets called is
std::string operator+(const std::string &s, char c); // actually it's basic_string<> with some CharT...
Or the +=
variant ;)
On how to find all the calls. You could compile (w/o inlining) all the code, objdump
it, grep
for all the operator occurrences and use addr2line
on the filtered addresses:
$ 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
This however hasn't given me the line number... At least the call site is there ;)
The -C
switch enables c++ name demangling. Which can also be done manually with binutls c++filt
.
Funnily enough, there is a definition of operator+
for string
and char
, but only when using operator+=
the integer literal is converted to char
, I have to pass a char
literal (or value) for operator+
to be used.
To find the mangled name of your 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_
The last one is the name you are searching for - which can be used to grep w/o name demangling.
I really don't know a better way to do this... :/
精彩评论