Linker anomalies
Ali Çehreli
acehreli at yahoo.com
Thu Nov 7 18:45:21 UTC 2019
On 11/07/2019 04:14 AM, Luh wrote:
> Hey there,
>
> I figured out some strange behavior ;
>
> #1
> It seems that the linker doesn't check for the function declared twice
> first.
It's not the linker but the "compiler" that is concerned about these things.
> Instead, it says:
>
> "Error: class app.Child use of app.Parent.foo() is hidden by Child; use
> alias foo = Parent.foo; to introduce base class overload set"
That's an important warning where the programmer can get surprising
results depending on whether the object is used through the Parent
interface or the Child interface.
> but when we call it ( p.foo() ), then it returns the correct error
message.
It indicates to me that the compiler is performing certain checks lazily
likely for performance reasons.
> #2
> The template update() compiles fine until we call it.
That's common for templates: As long as it's syntactically correct, some
errors are delayed until instantiation time.
> Bizarre, isn't it ?
I've seen worse. :)
> code:
> ---
> void main()
> {
> auto p = new Parent();
> // Shows the wrong error message until uncommented
> //p.foo();
> // Compiles when commented
> //update(p);
> }
>
> class Child : Parent
> {
> override void foo() { }
> }
>
> class Parent
> {
> void foo() { }
> void foo() { }
Apparently, the compiler does not check whether an overload set has
ambiguities until actual use. I suspect the opposite would slow dow
compilation and cause frustration in some cases.
> }
>
> void update(T)(T object) if(is(T == Parent))
> {
> static if (is(T == Parent))
> {
> // Shouldn't compile
> ObjectThatDoesntExists.bar(T);
> }
> }
> ---
>
> Is this a bug ?
It should compile because ObjectThatDoesntExists may actually be present
when T==Parent depending on other conditions in the program. A simple
example:
// Called only in some case:
version (X) update(p);
// And that case happens to introduce ObjectThatDoesntExists:
version (X) {
class O {
void bar() {
}
}
O ObjectThatDoesntExists; // <-- Now the code will compile
} // version
Remember that ObjectThatDoesntExists may even be introduced by another
module, which may be compiled separately with e.g. different compilation
options (e.g. --version=X). So, it's not possible for the compiler to
detect such cases. It's an error only if the template is actually
instantiated.
Ali
More information about the Digitalmars-d-learn
mailing list