开发者

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... :/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜