Bug 4576 – [tdpl] 0/1 argument calls to overloaded function is allowed in presence of variadic function
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2010-08-03T12:27:15Z
Last change time
2022-08-15T12:20:28Z
Keywords
accepts-invalid, TDPL
Assigned to
No Owner
Creator
Andrej Mitrovic
Comments
Comment #0 by andrej.mitrovich — 2010-08-03T12:27:15Z
According to TDPL, this should be an ambiguous call and issue a compiler error:
import std.algorithm, std.array, std.stdio;
@property bool empty(T)(T[] a) { return a.length == 0; }
@property ref T front(T)(T[] a) { return a[0]; }
void popFront(T)(ref T[] a) { a = a[1 .. $]; }
V reduce(alias fun, V, R)(V x, R range)
{
for ( ; !range.empty; range.popFront()) {
x = fun(x, range.front);
}
return x;
}
double average() { return 2.0; }
double average(double) { return 3.0; }
// compute the avg of a set of numbers, passable directly or via an array
double average(double[] values...)
{
if (values.empty)
{
throw new Exception("Average of zero elements is undefined");
}
return reduce!((a, b) { return a + b; })(0.0, values) / values.length;
}
unittest {
average(); // This should not compile, but does
writeln(average()); // calls average(), returns 2.0
writeln(average(0)); // calls average(double), returns 3.0
assert(average(0) == 0); // fails, since it calls average() which returns 2.0
assert(average(1, 2) == 1.5);
assert(average(1, 2, 3) == 2);
// passing arrays and slices works too
double[] v = [1, 2, 3];
assert(average(v) == 2);
}
void main() { }
Comment #1 by andrej.mitrovich — 2010-08-03T12:29:27Z
Sorry for the mixed comments between TDPL and the ones I've added. The average(); call should issue a compiler error. And a 1-argument call average(0) should issue an error as well.
Comment #2 by nfxjfg — 2010-08-03T12:42:42Z
Keywords go into keyword field.
Comment #3 by andrej.mitrovich — 2010-08-03T12:54:15Z
(In reply to comment #2)
> Keywords go into keyword field.
Ah, thanks!
Comment #4 by andrej.mitrovich — 2013-09-17T12:48:04Z
Reduced test-case:
-----
void test(int[] arr...) { assert(1); }
void test() { assert(0); } // hijacks (shadows) above function
void main()
{
test(); // should fail at CT, not RT.
}
-----
Comment out the second function and the first one will be called. The `test()` call should be ambiguous and issue a compile-time error.
Comment #5 by razvan.nitu1305 — 2022-08-15T12:20:28Z
(In reply to Andrej Mitrovic from comment #4)
> Reduced test-case:
>
> -----
> void test(int[] arr...) { assert(1); }
> void test() { assert(0); } // hijacks (shadows) above function
>
> void main()
> {
> test(); // should fail at CT, not RT.
> }
> -----
>
> Comment out the second function and the first one will be called. The
> `test()` call should be ambiguous and issue a compile-time error.
The compiler sees that both functions match, however, the non-variadic one is more specialized and the variadic one. This is all described very well in the spec [1]. More specifically, point 5 in the section that I linked.
Closing as invalid.
[1] https://dlang.org/spec/function.html#function-overloading