Bug 5328 – The addressof-expression that should be rejected is accepted

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2010-12-06T08:56:00Z
Last change time
2015-06-09T05:11:45Z
Keywords
accepts-invalid
Assigned to
nobody
Creator
rayerd.wiz

Comments

Comment #0 by rayerd.wiz — 2010-12-06T08:56:21Z
// a.d void f(void function() m) { m(); } class A { this() { f(&A.m); // rejects-invalid => OK } /+static+/ void m() {} } void main() { f(&A.m); // accepts-invalid => BAD!! } $ dmd a.d a.d(7): Error: function a.f (void function() m) is not callable using argument types (void delegate()) a.d(7): Error: cannot implicitly convert expression (&this.A.m) of type void delegate() to void function() You will get the following result if you remove A.this constructor. $ dmd a.d object.Error: Access Violation
Comment #1 by nfxjfg — 2010-12-06T09:21:27Z
It's a feature, not a bug. You can take the address of methods without providing an object reference (i.e. no this pointer, or what would be the context member of method delegates). The returned function pointer is simply what the class' vtable contains. The function signature is the same as the signature of a proper delegate to the method. It doesn't make sense to call the function pointer by itself (wrong calling convention, this pointer is missing), but it's useful for other things. E.g. you can use the type of the function pointer value in meta programming to get the method's signature. That's very important for meta programming. You could just instantiate a new object, and then analyze the delegate, but why should you need to construct a dummy object? For the actual value of the function pointer there are also valid uses. Think about serialization of delegates, for example. Note that the delegate property .funcptr return a similarly non-sensical function pointer. The context is missing and the calling convention is incompatible. If you call it, you get an access violation as well. What is happening here is that the language "designers" just didn't feel like introducing a dedicated separate function type for this purpose. Instead, they reused the "normal" function pointer type, even if calling it makes no sense. Basically it's a quick language hack that endangers type-safety and confuses users. Btw. the code inside A.this is not accepted, because the "A." from "&A.m" just qualifies the member "m". Inside the ctor it's exactly the same as writing "&m". And &m is a delegate, not a function. So everything is alright. Though this slight syntactic ambiguity is another hint that D as a language is actually quite unorthogonal and full of special cases. Maybe "&typeof(this).m" in the ctor would do the same as the &A.m in main()?
Comment #2 by clugdbug — 2010-12-06T23:35:07Z
(In reply to comment #1) > It's a feature, not a bug. You can take the address of methods without > providing an object reference (i.e. no this pointer, or what would be the > context member of method delegates). > What is happening here is that the language "designers" just didn't feel like > introducing a dedicated separate function type for this purpose. Instead, they > reused the "normal" function pointer type, even if calling it makes no sense. > Basically it's a quick language hack that endangers type-safety and confuses > users. Are you sure this is an intentional design decision, and not just an oversight? Was it discussed by Walter and Andrei in the newsgroup?
Comment #3 by yebblies — 2011-06-18T23:35:49Z
*** This issue has been marked as a duplicate of issue 3720 ***