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.