1

同僚が std::string に整数を追加できると考えており、そのような操作をコードのあちこちで使用していることがわかりました。

この操作でコンパイラ エラーは発生しません。理由がわかりませんoperator+ (const string& lhs, int rhs);。int は暗黙のうちに char にキャストされますか? (gcc Red Hat 4.1.2 および -Wall スイッチでコンパイル)。

そして、最も重要なのは、int が std::string に追加されたすべての行をどのように見つけるのでしょうか?

4

1 に答える 1

3

同僚が整数リテラルのみを使用した場合、これらは次のように変換されcharます - ただし、整数の値が大きすぎる場合は警告が表示されます。呼び出されるオペレーターは

std::string operator+(const std::string &s, char c); // actually it's basic_string<> with some CharT...

または+=バリアント;)

すべての呼び出しを見つける方法について。すべての演算子の出現に対してすべてのコードを (インライン化なしで) コンパイルし、フィルター処理されたアドレスで使用することobjdumpができます。grepaddr2line

$ 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


おかしなことに、forとの定義がありますが、整数リテラルを に変換する場合にのみ、 for を使用するためにリテラル (または値)を渡す必要があります。operator+stringcharoperator+=charcharoperator+


オペレーターのマングル名を見つけるには:

$ 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_

最後の 1 つは、検索している名前です。これは、名前のデマングリングなしで grep するために使用できます。

これを行うためのより良い方法が本当にわかりません... :/

于 2010-12-23T08:37:34.497 に答える