Bug 2999 – Return-type overloading should be error

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2009-05-17T06:12:49Z
Last change time
2019-09-10T09:11:19Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
Shin Fujishiro
Depends on
1003

Comments

Comment #0 by rsinfu — 2009-05-17T06:12:49Z
This code compiles without error: -------------------- short foo() { return 1; } int foo() { return 2; } -------------------- Yes, the above example is not so serious because if you try to use foo, the compiler will spit an error. But it will be serious when function overriding is involved: -------------------- interface I { short foo(); } interface J { int foo(); } class C : I, J { override short foo() { return 1; } override int foo() { return 2; } } void main() { I i = new C; J j = new C; writeln(i.foo); writeln(j.foo); } -------------------- The compiler silently accepts this code. And the result is: -------------------- 1 10289153 -------------------- Note that the lower 16-bit of 10289153 is 1. Thus, the short foo() is invoked. If the declaration order of C.foo is reversed, the result becomes -------------------- 2 2 -------------------- In this case, int foo() is invoked.
Comment #1 by andrej.mitrovich — 2012-01-21T18:03:49Z
The compiler doesn't accept this code anymore in 2.057, marking as fixed.
Comment #2 by andrej.mitrovich — 2014-03-24T14:34:11Z
(In reply to comment #1) > The compiler doesn't accept this code anymore in 2.057, marking as fixed. I must have tested the second snippet but not the first, as the first still compiles: ----- short foo() { return 1; } int foo() { return 2; } -----
Comment #3 by andrej.mitrovich — 2014-03-24T14:34:24Z
*** Issue 12454 has been marked as a duplicate of this issue. ***
Comment #4 by hsteoh — 2014-07-15T04:47:17Z
Wow this one is pretty funny: ----- short foo() { return 1; } int foo() { return 2; } void main() { short s = foo(); int i = foo(); import std.stdio; writeln(s); writeln(i); } ----- Compiler output: ----- test.d(4): Error: test.foo called with argument types () matches both: test.d(1): test.foo() and: test.d(2): test.foo() test.d(5): Error: test.foo called with argument types () matches both: test.d(1): test.foo() and: test.d(2): test.foo() ----- That's hilarious, since there's no way you can actually disambiguate between them! (Not that I know of, anyway.)
Comment #5 by razvan.nitu1305 — 2019-09-10T09:11:19Z
Running the second examples now yields: 1 2 This is the expected behavior. The first example still compiles. I assume that this is necessary in order to facilitate the compilation of the second example (for consistency reasons). In D, you have to implement both foo methods, so you must have the ability of overloading based on return type. Note that instantiating a C and calling foo will output an error. C c = new C; writeln(c.foo()); // foo called with arguments () matches both definitions Closing as WORKSFORME.