I read this line in a book:
It is provably impossible to build a compiler that can actually determine whether or not a C++ function will change the value of a particular variable.
The paragraph was talking about why the compiler is conservative when checking for const-ness.
Why is it impossible to build such a compiler?
The compiler can always check if a variable is reassigned, a non-const function is being invoked on it, or if it is being passed in as a non-const parameter...
Address of local variables are not known, because they reside on "stack" memory region. Stack winding-unwinding of a program may defer based on runtime conditions of the code flow.
There are many things within C that are implementation-defined. This means that the people who create the compilers can choose how they want to handle those situations. In general, for portability it is best in most cases to not rely on undefined behavior, even when most or all compilers handle it the same way.
Accessing C Code from Within C++ SourceAll C++ compilers also support C linkage, for some compatible C compiler. When you need to access a function compiled with C linkage (for example, a function compiled by the C compiler, or a function written in assembler), declare the function to have C linkage.
As for compilers, both languages have long histories, and have existed long enough that there were many “payware” compilers for them, and C - in particular - is simple enough to compile that there were numerous compilers for it “back in the day”.
Why is it impossible to build such a compiler?
For the same reason that you can't write a program that will determine whether any given program will terminate. This is known as the halting problem, and it's one of those things that's not computable.
To be clear, you can write a compiler that can determine that a function does change the variable in some cases, but you can't write one that reliably tells you that the function will or won't change the variable (or halt) for every possible function.
Here's an easy example:
void foo() { if (bar() == 0) this->a = 1; }
How can a compiler determine, just from looking at that code, whether foo
will ever change a
? Whether it does or doesn't depends on conditions external to the function, namely the implementation of bar
. There's more than that to the proof that the halting problem isn't computable, but it's already nicely explained at the linked Wikipedia article (and in every computation theory textbook), so I'll not attempt to explain it correctly here.
Imagine such compiler exists. Let's also assume that for convenience it provides a library function that returns 1 if the passed function modifies a given variable and 0 when the function doesn't. Then what should this program print?
int variable = 0; void f() { if (modifies_variable(f, variable)) { /* do nothing */ } else { /* modify variable */ variable = 1; } } int main(int argc, char **argv) { if (modifies_variable(f, variable)) { printf("Modifies variable\n"); } else { printf("Does not modify variable\n"); } return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With