Search code examples
c++assertlibstdc++std

Is there any reason standard library implementations do not use asserts when compiling without -DNDEBUG and -O3?


Countless time I wrote code that generated a segmentation fault after accessing an std::vector or an std::string outside its memory:

std::string test{"hello!"};
std::cout << test[12] << std::endl;

This is an error that could be caught at run-time in non-optimized/debug builds, with a small additional cost of a simple assertion. (But since we're building without -DNDEBUG and without -O3 we're not expecting to get maximum performance.)

Is there any reason why std::string::operator[] isn't implemented like this?

Does the standard forbid use of asserts in library code?

char std::string::operator[](std::size_t i)
{
    // `assert_with_message` only exists in debug mode

    #ifndef NDEBUG
        assert_with_message(i < this->size(),
            "Tried to access character " + std::to_string(i)
            + " from string '" + *this + "' of size " 
            + std::to_string(this->size()));
    #endif

    return data[i];
}

It would be really helpful to compile the program without -DNDEBUG and see something similar to this message at runtime:

Assertion fired: Tried to access character 12 from string 'hello!' of size 6.

Press (0) to continue.

Press (1) to abort.

Note that by the term assert I'm referring to a development/debug build check that should be completely removed/optimized-out from release/optimized builds.


Solution

  • Several implementations of the standard library do provide such checks in debug mode, but debug mode is not controlled by NDEBUG. For libstdc++, you need -D_GLIBCXX_DEBUG (see the doc).