c++ccompiler-warningsdereferencenull-pointer

Why do compilers not warn about this null dereferencing, even when they detect it?


Consider the following program:

int main() {
    int* ptr = nullptr;
    return *ptr + 1;
}

(also on GodBolt)

How is it, that with "decent" warnings enabled (-Wall -Wextra), both popular compilers - clang++ 20.1.0, g++ 15.1 - fail to warn me about the null pointer dereferencing? Especially since they realize they don't need to bother adding 1?

Note: Same behavior if I compile it as C instead of C++.


Solution

  • tl;dr: Because you didn't specifically ask for warnings about null dereferencing.

    clang and GCC have a specific warning flag for this. Quoting the GCC man page:

    -Wnull-dereference
        Warn if the compiler detects paths that trigger erroneous or undefined 
        behavior due to dereferencing a null pointer.  This option is only
        active when -fdelete-null-pointer-checks is active, which is enabled by 
        optimizations in most targets.  The precision of the warnings depends
        on the optimization options used.
    

    I have not observed -fdelete-null-pointer-checks to have any effect on clang and GCC however, only by the optimization level and this flag. Here is how the effects seem to work right now (clang 20, GCC 15.1):

    Compiler Optimization level -Wnull-dereference Other flags? Warning?
    clang (none) On No
    clang (none) Off No
    GCC (none) On No
    GCC (none) Off No
    clang -O1 or higher On No (*)
    clang -O1 or higher Off No (*)
    GCC -O1 or higher On Yes
    GCC -O1 or higher Off No
    GCC (any) (any) -fanalyzer Yes

    (*) If you fully-hand-inline everything:

    int main() {
        return *(int*)(0) + 1;
    }
    

    clang will catch the null dereferencing (provided -Wnull-dereference)


    What are we seeing here?

    1. A clang bug in the case of -O1 or higher and -Wnull-dereference. Thanks @n.m.canbeai for suggesting that. It is bug 113068, already reported last year.
    2. Both compilers are being very lazy in their static analysis even when you ask them for -Wnull-dereference. Is this a good idea? I would say no, or at least - you should be able to tell the compiler "even though I'm not asking for optimization, I do want you to statically analyze seriously".
    3. Both compilers don't believe that checking for null dereferences should be part of "all" warnings, nor even part of the "extra" warnings. IMNSHO that is quite bad, since a user is quite likely to assume that this check is part of one of those two.
    4. Both compilers avoid warning about null-dereferencing when not explicitly asked to do so, despite detecting - at some level - that it happens, and despite not being asked to suppress all warnings. This is not as bad, but still somewhat questionable.
    5. GCC's static analyzer, applicable from "within" the compiler, helps (at least in some cases).