Summary: Symbols named init should be illegal
Product: D
Version: unspecified
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: DMD
AssignedTo: nob...@puremagic.com
ReportedBy: jmdavisp...@gmx.com
--- Comment #0 from Jonathan M Davis <jmdavisp...@gmx.com> 2012-10-14 00:04:46
PDT ---
The fact that the compiler currently allows any symbols to be named init just
causes problems. For instance, take this program:
struct S
{
int i = 2;
this(int j)
{
assert(i == 2);
i = j;
}
@property static init()
{
return S(5);
}
}
void main()
{
assert(S.init == S(2));
}
The assertion in main fails, while the assertion in the constructor succeeds.
That means that it's failing to actually override the init property for S
(which is good), but now the init property for S is inaccessible. This is
dangerous and will break all kinds of code. This sort of thing should just be
disallowed. It gains us nothing and just causes problems. Similarly, this code
struct S
{
int i = 2;
this(int j)
{
assert(i == 2);
i = j;
}
@property S init()
{
return S(5);
}
}
void main()
{
assert(S.init == S(2));
}
results in this compilation error:
q.d(19): Error: need 'this' for init type @property S()
So, again, it makes it impossible to access the type's init property.
For some reason, TDPL (p. 275) specifically permits enums to declare min, max,
and init properties, though it _does_ tell you that it's a bad idea to do so.
So, if that's to be permitted, init would still have to be allowed there, but
I'd strongly argue that that should be changed. And note that just like with
structs, it causes weird issues:
enum MyEnum : int { a, b, c, init }
void main()
{
MyEnum e;
assert(e == MyEnum.a);
assert(MyEnum.init == MyEnum.a);
}
The first assertion passes but the second fails, meaning that once again, you
can't get at the init property of the type anymore. Sure, declaring init as the
first value fixes that, but init would be the first value anyway if init
weren't explicitly declared. See issue# 8816.
The only situation where explicitly declaring init might make some sense would
be to @disable it, but the syntax for disabling init is @disable this(); and
not anything directly involving init. You can try and declare
struct S
{
int i;
@disable static S init;
}
void main()
{
S s;
}
but it compiles just fine.
At minimum, I would strongly argue that any and all symbols which could
conflict with the actual init property for a type should be made illegal. There
are a few cases where it may not cause problems (e.g. a local variable), but
I'd argue that it would be cleaner to just disallow those as well. If need be,
maybe init should become a keyword. Certainly, the current situation just
permits bugs and the ability to declare symbols named init which conflict with
the actual init property for a type needs to be eliminated.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------