c++ 如何通过检查优化的编译器输出来防止在生成时从nullptr构造std::string

z4iuyo4d  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(135)

当GCC的优化器检测到std::string使用了nullptr编译时,它不会输出警告。我找到了一个解决方法,只是想知道是否有更好的方法。它利用了std::string实现的一个Assert在使用nullptr构造时会触发。所以通过使用优化进行编译并查看程序集,我可以看到那一行。
注意,下面只是一个例子,这不是应用程序代码。但是,我想知道是否有比我所做的更好的方法。我用这个特定的字符串搜索__throw_logic_error。
我从godbolt.org粘贴了这个代码,可以用GCC 12编译如下:

g++ -O1 -S -fverbose-asm -std=c++23 -Wall -o string.s string.cpp

#include <string>
void f()
{
    const char * a = nullptr;
    std::string s(a);
}

int main()
{
   f();
}



.LC0:
        .string "basic_string: construction from null is not valid"
f():
        sub     rsp, 8
        mov     edi, OFFSET FLAT:.LC0
        call    std::__throw_logic_error(char const*)
main:
        sub     rsp, 8
        call    f()
mzsu5hc0

mzsu5hc01#

抛出异常原则上是法律的的(这是logic_error的问题,它们不应该是异常)。
由于这个原因,我怀疑编译器是否会抱怨这一点,即使它可以在编译时计算所有值。最好的选择是静态分析器。
上帝 lightning 中的叮当-整齐版本,可以检测到这一点,

warning: The parameter must not be null [clang-analyzer-cplusplus.StringChecker]

https://godbolt.org/z/h9GnT9ojx
这一点已纳入clang-tidy 17,https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-stringchecker-c
在编译器警告行中,您可能会幸运地(最终)遇到类似的情况,尽管我并不幸运。

void f() {
    const char * a = nullptr;
    try {
        std::string s(a);
    }catch(std::logic_error&) {
        std::unreacheable();  // or equivalent for current GCC
    }
}

相关问题