How to prevent std::string being constructed from a nullptr at build time by checking the optimized compiler output

315 views Asked by At

GCC doesn't output a warning when it's optimizer detects std::string being compiled with a nullptr. I found a workaround, just wondering if anything better. It takes advantage of the std::string implementation having an assert that fires when constructed with nullptr. So by compiling with optimisation and looking at the assembly, I can see that line.

Note, below is just an example, this isn't application code. However, I wondered if there is a better way than what I do. I search for __throw_logic_error with that particular string.

I've pasted this from godbolt.org. Can be compiled with GCC 12 as follows:

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()
1

There are 1 answers

6
alfC On

Throwing an exception could be in principle a legal use. (This is the problem with logic_error's, they shouldn't be exceptions.)

For this reason, I doubt that a compiler will ever complain about this, even if it can evaluate all at compile time. Your best bet is a static analyzer.

The version of clang-tidy in godbolt, can detect this,

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

https://godbolt.org/z/h9GnT9ojx

This was incorporated in clang-tidy 17, https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-stringchecker-c


In the lines of compiler warnings you could be lucky (eventually) with something like this, although I wasn't lucky.

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