Reputation: 7155
Compiling the following cause T::f()
to be optimized-out without any warning or error:
#include <iostream>
struct T
{
int t;
void f(); //undefined..
};
int main()
{
T t;
t.t = 1;
//t.f(); //<-- compiler-error only when used, otherwise optimized-out
std::cout << t.t;
return 0;
}
Background: I used stub-declarations for functions in a class with intention to later define and use them. 'Later' never came, and my code compiled & the compiler issued no warnings or errors about these stubs.
Is this expected from the compiler?; shouldn't the compiler at least issue warnings?
Upvotes: 1
Views: 113
Reputation: 726479
This is not an "optimization". C++ compiler lets you declare anything that you wish, provided that the declaration is valid syntactically, and does not reference undefined types. This is not specific to member functions: non-member functions and global variables can be declared without providing a corresponding definition.
It turns out that neither the compiler nor the linker are in a good position to complain about unfulfilled declaration. Even issuing a warning would be problematic due to the possibility of separate compilation.
Compiler will not complain, because it knows that another cpp file may provide the definition, and by the time the linker runs, the declaration is gone: linker works with definitions and references, while declarations are for the compiler.
From a comment:
There are hundreds (or even thousands) "not called by app" functions in system .h files. The compiler doesn't know where the code resides: either in your .cpp source, or in precompiled .obj/.o, or in .dll/.so etc.etc. It's linker's duty, not the compiler's one. So the compiler silently ignores every signature without "body". – user4419802
Upvotes: 4
Reputation: 12999
The compiler hasn't optimized anything out because there was nothing there to optimize out in the first place. When you declared void T::f();
all you did was add a method signature to the compiler's internal dictionary, if you like. You never gave the method a corresponding body and you never called it so it simply 'never happened'.
Upvotes: 2
Reputation: 310840
The compiler doesn't know whether you're going to declare T::f()
in another compilation unit, and it doesn't care, because it 'knows' you will get a linker error if you don't.
Upvotes: 1