Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 26, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 Adam D. Ruppe <destructionator@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |doob@me.com -- |
February 26, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #1 from Jacob Carlborg <doob@me.com> --- Here's the problem. What's happening in your example is that the whole NSString class is overwritten. When a class is referenced and only declared, a specific symbol is outputted by the compiler. When the class is defined as well additional symbols are outputted as well. Since these symbols are located in the object file the linker won't search for them in external libraries. It's the same thing as doing: extern (C) void* malloc(size_t size) { return null; } I currently don't have a good way to determine if a class is externally defined or not. The current implementation will assume that it is externally defined if none of the methods have a body. This is not an ideal solution, it causes this problem, as you have noticed. It's also not possible to have an empty subclass. I think the original implementation required to use `extern (Objective-C)` on externally defined classes and not use it on internally defined classes. That requires that all classes defined in D inherit from an externally defined class. This is true most of the time, the Objective-C compiler will warn if you don't inherit from a class. In Objective-C this is easily handled by having two separate keywords for declarations and definitions: @interface Foo // declaration of a class named Foo @end @implementation Foo // definition of Foo @end I'll try to figure out how this is handled in Swift. -- |
February 26, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #2 from Adam D. Ruppe <destructionator@gmail.com> --- OK, I see. Well, in the mean time, at least now that I know what is causing this, it is very easy to work around. (It was just crazy at first to narrow it down, and since I frequently "comment" stuff with `version(none)` and that didn't change it, I thought I was crazy when it went away.) It is arguably bad form to include those extern(D) overloads side by side, though it is convenient, it isn't necessary. So, a possible fix to consider would just be to make it an error to mix extern declarations and body functions in the same class definition (excluding inherited declarations). -- |
February 26, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #3 from Jacob Carlborg <doob@me.com> --- (In reply to Adam D. Ruppe from comment #2) > OK, I see. Well, in the mean time, at least now that I know what is causing this, it is very easy to work around. (It was just crazy at first to narrow it down, and since I frequently "comment" stuff with `version(none)` and that didn't change it, I thought I was crazy when it went away.) > > It is arguably bad form to include those extern(D) overloads side by side, though it is convenient, it isn't necessary. So, a possible fix to consider would just be to make it an error to mix extern declarations and body functions in the same class definition (excluding inherited declarations). I don't think that would work. Because then this won't work: extern (Objective-C) class NSObject { NSObject init() @selector("init"); static NSObject alloc() @selector("alloc"); } extern (Objective-C) class Foo : NSObject { override Foo init() @selector("init"); override static Foo alloc() @selector("alloc"); void foo() @selector("foo") { } } In Foo we override "init" and "alloc" just to get the correct static return type. I think the above example has to work. -- |
February 26, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #4 from Jacob Carlborg <doob@me.com> --- BTW, I don't think Objective-C classes in D has a vtable, so adding `extern (D)` methods won't work anyway. But final `extern (D)` methods do work. -- |
February 26, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #5 from Adam D. Ruppe <destructionator@gmail.com> --- Oh yeah, you're right. I forgot about that (even after writing it ten times while playing with it lol). Blargh. -- |
February 27, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #6 from Jacob Carlborg <doob@me.com> --- An alternative would be to need to write `extern(Objective-C) extern class NSString` for classes defined externally. -- |
February 28, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #7 from Jacob Carlborg <doob@me.com> --- How about, instead of just checking for methods with a body, the compiler can require the linkage to be Objective-C, for a class to be considered defined internally? -- |
February 28, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 --- Comment #8 from Adam D. Ruppe <destructionator@gmail.com> --- Huh, I don't know. I kinda like `extern extern` - there's precedent for that in accessing C variables declared elsewhere, and the Objective-C class is similar to that. But, I don't know for sure. -- |
March 01, 2019 [Issue 19700] [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19700 Dlang Bot <dlang-bot@dlang.rocks> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull --- Comment #9 from Dlang Bot <dlang-bot@dlang.rocks> --- @jacob-carlborg created dlang/dmd pull request #9402 "Fix issue 19700: Obj-C wrong code overloading selectors and extern(D)" fixing this issue: - Fix issue 19700: Obj-C wrong code overloading selectors and extern(D) The issue is that if an Objective-C class contains at least one method with a body it will be considered an internally defined class. This means that for a declaration for a class that is supposed to be defined externally it won't look for this class externally when linking. Basically the internally defined class has taken precedence over the externally defined class. When some of the methods don't have a body a runtime exception will occur in the Objective-C runtime when they're called. The fix is to require `extern (Objective-C) extern` for externally defined classes. For internally defined classes, `extern (Objective-C)` is used. https://github.com/dlang/dmd/pull/9402 -- |
Copyright © 1999-2021 by the D Language Foundation