Perché non std: string + int dare compilazione errore?
-
12-10-2019 - |
Domanda
Abbiamo appena trovato il nostro collega pensava che può aggiungere un numero intero a std :: string e tale operazione utilizzato qua e là nel suo codice.
Non si vede alcun errore di compilazione per questa operazione e io non capisco perché: non c'è operator+ (const string& lhs, int rhs);
. È int silenziosamente colato a char? (La compilazione con gcc 4.1.2 Red Hat e l'interruttore -Wall).
E, cosa più importante, come facciamo a trovare tutte le linee in cui int aggiunto al std :: string?
Soluzione
Quando il vostro collega utilizzato solo numeri interi letterali, questi saranno convertiti in char
- Verrà comunque visualizzato un avviso se il valore del numero intero è troppo grande. L'operatore che viene chiamato è
std::string operator+(const std::string &s, char c); // actually it's basic_string<> with some CharT...
In alternativa la variante +=
;)
su come trovare tutte le chiamate. Si potrebbe compilare (w / o inlining) tutto il codice, objdump
esso, grep
per tutte le occorrenze operatore e l'uso addr2line
sugli indirizzi filtrati:
$ 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
Questo però non mi ha dato il numero di riga ... Almeno il sito chiamata c'è;)
L'interruttore -C
consente C ++ nome di decodifica. Che può anche essere fatto manualmente con binutls c++filt
.
Stranamente, ci è una definizione di operator+
per string
e char
, ma solo quando si utilizza operator+=
letterale intero viene convertito in char
, devo passare un letterale char
(o valore) per operator+
per essere utilizzato.
Per trovare il nome storpiato del proprio operatore :
$ 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_
L'ultimo è il nome che si sta cercando -. Che può essere utilizzato per grep w / o nome di decodifica
Io davvero non so un modo migliore per fare questo ...: /