Почему std: string + int не дает ошибку компиляции? - PullRequest
1 голос
/ 23 декабря 2010

Мы только что обнаружили, что наш коллега думал, что он может добавить целое число к std :: string, и использовали эту операцию здесь и там в своем коде.

Мы не видим никаких ошибок компилятора для этой операции, и я не понимаюне понимаю почему: нет operator+ (const string& lhs, int rhs);.Int молча приведен к char?(Компиляция с gcc Red Hat 4.1.2 и ключом -Wall).

И, самое главное, как нам найти все строки, где int добавлен в std :: string?

1 Ответ

3 голосов
/ 23 декабря 2010

Когда ваш коллега использовал только целочисленные литералы, они будут преобразованы в char - однако вы увидите предупреждение, если значение целого числа слишком велико.Вызываемый оператор:

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

или вариант +=;)

О том, как найти все вызовы.Вы можете скомпилировать (без встраивания) весь код, objdump it, 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+ для string и 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_

Последнее - это имя, которое вы ищете, - которое можно использовать для поиска без имени.

Я действительно не знаю лучшего способа сделать это ...: /

...