Home > Blockchain >  Why can't C 20 compliant compilers detect memory leaks?
Why can't C 20 compliant compilers detect memory leaks?

Time:10-09

In C 20 we can allocate memory in constexpr contexts as long as the memory is freed within the context — i.e this is valid:

constexpr int* g(){
    int* p = new int(100);
    return p;
}

constexpr int f(){
    int* ret = g();
    int i = *ret;
    delete ret;
    return i;
}
static_assert(f() == 100);

Whereas this won't compile:

constexpr int* g(){
    int* p = new int(100);
    return p;
}

constexpr int f(){
    int* ret = g();
    int i = *ret;
    return i;
}
static_assert(f() == 100);

with the error:

error: '(f() == 100)' is not a constant expression because allocated storage has not been deallocated

Now this obviously means that the compiler is able to keep track of allocations and deallocations — at least in a constexpr context.

I can see how the compiler, being in control of allocations at compile-time, is better able to keep track of memory leaks, and of course, this says nothing of out-of-bounds accesses, use after frees, double frees etc, but surely the functionality that allows compile-time constexpr leak detection could be extended to some degree of general compile-time leak detection too?

Hence my question: Is there some fundamental limitation that prevents the compiler from performing leak-detection in non-constexpr contexts at compile time, or was the feature simply deemed unnecessary?

CodePudding user response:

surely the functionality that allows compile-time constexpr leak detection could be extended to some degree of general compile-time leak detection too?

No, it can't.

Compile-time code execution means that the compiler is executing the code. That is the "functionality that allows compile-time constexpr leak detection": the fact that the compiler is doing it.

Non-compile-time execution is governed by the machine code generated by the compiler. By the time the code is executed, the compiler is long-since out of the picture. In order to have leak detection, the compiler would have to generate a bunch of extra code into this machine code to do the checking. Which would be slow.

Furthermore, compile-time code is necessarily limited. Most of the tricks that make this hard are expressly forbidden. Chucking reinterpret_cast and its equivalents alone removes an entire layer of complexity from the problem. You can't throw exceptions either, so that's another source of leak-detection difficulties you don't have to consider. Most of the things that make leak detection hard simply cannot be done in constexpr code.

  • Related