Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
August 10, 2018 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: |
August 10, 2018 Re: is this a bug ? mixin template static function missing! | ||||
---|---|---|---|---|
| ||||
Posted in reply to learnfirst1 | 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. |
August 10, 2018 Re: is this a bug ? mixin template static function missing! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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();
}
|
August 10, 2018 Re: is this a bug ? mixin template static function missing! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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.
|
August 10, 2018 Re: is this a bug ? mixin template static function missing! | ||||
---|---|---|---|---|
| ||||
Posted in reply to learnfirst1 | 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
|
August 10, 2018 Re: is this a bug ? mixin template static function missing! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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. |
Copyright © 1999-2021 by the D Language Foundation