【问题标题】:Why does not std:string + int give compilation error?为什么 std:string + int 不给出编译错误?
【发布时间】:2011-05-29 20:31:12
【问题描述】:

我们刚刚发现我们的同事认为他可以将整数添加到 std::string 并在他的代码中到处使用这种操作。

我们没有看到此操作的任何编译器错误,我不明白为什么:没有operator+ (const string& lhs, int rhs);。 int 是否被默默地转换为 char? (使用 gcc Red Hat 4.1.2 和 -Wall 开关编译)。

而且,最重要的是,我们如何找到将 int 添加到 std::string 的所有行?

【问题讨论】:

    标签: gcc stl g++ stdstring name-mangling


    【解决方案1】:

    当您的同事只使用整数文字时,这些文字将被转换为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 手动完成。


    有趣的是,对于stringchar定义了operator+,但只有在使用operator+= 时,整数文字才会转换为char,我必须为要使用的operator+ 传递一个char 文字(或值)。


    要查找您的运营商的错位名称

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

    最后一个是您要搜索的名称 - 可用于 grep w/o name demangling。

    我真的不知道更好的方法来做到这一点...:/

    【讨论】:

    • -C 开关代表什么?我的 CentOS objdump 中没有它。
    • 它对 c++ ABI 名称进行了解码。没有它,std::string::operator+=(char) 被命名为_ZNSspLEc
    • 其实我的 objdump 确实有开关。它只是没有在帮助中列出。
    • 可能的杰克。不要使用它并搜索损坏的运算符名称。编译一个执行str+'a'、objdump -t a.out|c++filt 的测试程序,在没有c++filt 的情况下获取operator+objdump -t 的地址,并检查地址以获得损坏的名称。
    猜你喜欢
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多