is this a bug ? mixin template static function missing!
#!/usr/bin/env rdmd import core.stdc.stdio; template G(size_t line = __LINE__, A...){ int i = 3; static extern(C) pragma(crt_constructor) void init2(){ printf("init: %d\n", line); } } pragma(crt_constructor) extern(C) void init1(){ printf("init from global\n"); } struct A { mixin G!(); } extern(C) void main(){ mixin G!() g; printf("g.i=%d\n", g.i); g.init2(); // remove this can build, but g.init2 not get called! } - build error: Undefined symbols for architecture x86_64: "__D4test4mainUZ1g5init2UNbNiZv", referenced from:
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 08:31:21 UTC, learnfirst1 wrote: #!/usr/bin/env rdmd import core.stdc.stdio; template G(size_t line = __LINE__, A...){ int i = 3; static extern(C) pragma(crt_constructor) void init2(){ printf("init: %d\n", line); } } pragma(crt_constructor) extern(C) void init1(){ printf("init from global\n"); } struct A { mixin G!(); } extern(C) void main(){ mixin G!() g; printf("g.i=%d\n", g.i); g.init2(); // remove this can build, but g.init2 not get called! } - build error: Undefined symbols for architecture x86_64: "__D4test4mainUZ1g5init2UNbNiZv", referenced from: It is indeed. Reduced example: template G(){ extern(C) pragma(crt_constructor) void init(){} } void main(){ mixin G!(); init(); } For nested functions, extern(C) is simply ignored[0]. Since pragma(crt_constructor) requires that the symbol it's applied to uses C linkage (and an error message to that effect is shown if you write pragma(crt_constructor) void fun() {} in module scope: Error: function `fun` must be extern(C) for pragma(crt_constructor) In addition, if you try to apply pragma(crt_constructor) to a nested function, you get this error message, showing further that nested functions can't be crt_constructors: Error: unrecognized pragma(crt_constructor) The correct behavior would be for the compiler to show the latter error message for a mixin'd function as well. Filed a bug: https://issues.dlang.org/show_bug.cgi?id=19153 -- Simen [0]: from https://dlang.org/spec/attribute.html#linkage: Note that extern(C) can be provided for all types of declarations, including struct or class, even though there is no corresponding match on the C side. In that case, the attribute is ignored. This behavior applies for nested functions and nested variables as well.
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 10:24:55 UTC, Simen Kjærås wrote: On Friday, 10 August 2018 at 08:31:21 UTC, learnfirst1 wrote: The correct behavior would be for the compiler to show the latter error message for a mixin'd function as well. Filed a bug: https://issues.dlang.org/show_bug.cgi?id=19153 -- Simen I think the static extern(C) nested function should just work like global extern(C) function. DMD still report missing symbols. Or I am wrong about this ? template G(){ static extern(C) pragma(crt_constructor) void init(){} } void main(){ mixin G!(); // Line 5 init(); }
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 10:24:55 UTC, Simen Kjærås wrote: On Friday, 10 August 2018 at 08:31:21 UTC, learnfirst1 wrote: Filed a bug: https://issues.dlang.org/show_bug.cgi?id=19153 template G(){ pragma(crt_constructor) static extern(C) void init(){} } void main(){ mixin G!(); // Line 5 init(); } same missing symbols.
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 11:17:10 UTC, learnfirst1 wrote: I think the static extern(C) nested function should just work like global extern(C) function. DMD still report missing symbols. Or I am wrong about this ? template G(){ static extern(C) pragma(crt_constructor) void init(){} } void main(){ mixin G!(); // Line 5 init(); } If you try the same without the mixin template, you'll see that it doesn't work: void main() { static extern(C) pragma(crt_constructor) void init(); init(); } Depending on the order of static, extern(C) and pragma(crt_constructor), you can get at least two different error messages, but either way - it doesn't work. It would be possible to make this work by changing the compiler, but according to spec, it shouldn't. -- Simen
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 12:05:52 UTC, Simen Kjærås wrote: On Friday, 10 August 2018 at 11:17:10 UTC, learnfirst1 wrote: If you try the same without the mixin template, you'll see that it doesn't work: struct Test { extern(C) pragma(crt_constructor) static void init(){ // work int i = 3; } } void main(){ extern(C) pragma(crt_constructor) static void init(){ // not work int i = 3; } } -- It not work make no sense, since it can work on struct. I am not be able to search the related spec docs, only this link: https://dlang.org/blog/2018/01/04/dmd-2-078-0-has-been-released/ Based on my understand, nested static extern(C) function is all about visibility. It just like put private before it, there is really no reason to treat them in diff way.