Thread overview | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 23, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla@digitalmars.com --- Comment #1 from Walter Bright <bugzilla@digitalmars.com> --- It is exported, just as: __D4test8__mixin43fooUZv instead of: _foo You can see what's exported by running obj2asm on the .obj file, don't need to use GetProcAddress. For example: --- export extern(C) void fun() {} mixin template M() { export extern(C) void bar() {} } mixin M!(); --- dmd -c test.d obj2asm test.obj --- _TEXT segment dword use32 public 'CODE' ;size is 0 _TEXT ends _DATA segment para use32 public 'DATA' ;size is 0 _DATA ends CONST segment para use32 public 'CONST' ;size is 13 CONST ends _BSS segment para use32 public 'BSS' ;size is 0 _BSS ends FLAT group extrn _fun ;expdef expflag=x00, export '_fun', internal '', ordinal=x0 extrn __D4test8__mixin43barUZv ;expdef expflag=x00, export '__D4test8__mixin43barUZv', internal '', ordinal=x0 FMB segment dword use32 public 'DATA' ;size is 0 FMB ends FM segment dword use32 public 'DATA' ;size is 4 FM ends FME segment dword use32 public 'DATA' ;size is 0 FME ends public __D4test12__ModuleInfoZ _fun COMDAT flags=x0 attr=x0 align=x0 __D4test8__mixin43barUZv COMDAT flags=x0 attr=x10 align=x0 _TEXT segment assume CS:_TEXT _TEXT ends _DATA segment _DATA ends CONST segment __D4test12__ModuleInfoZ: db 004h,010h,000h,000h,000h,000h,000h,000h ;........ db 074h,065h,073h,074h,000h ;test. CONST ends _BSS segment _BSS ends FMB segment FMB ends FM segment dd offset FLAT:__D4test12__ModuleInfoZ FM ends FME segment FME ends _fun comdat assume CS:_fun ret _fun ends __D4test8__mixin43barUZv comdat assume CS:__D4test8__mixin43barUZv ret __D4test8__mixin43barUZv ends end --- -- |
July 23, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #2 from Manu <turkeyman@gmail.com> --- Right. We'll, that's obviously broken :) -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #3 from Walter Bright <bugzilla@digitalmars.com> --- Is it? Note the same behavior happens with: struct S { extern (C) void foo() { } } i.e. foo() gets mangled. There are two aspects of C mangling - one is the ABI, the other is the ABI. Using C mangling in a scope means there can be only one, so D just uses it to set the ABI. But there's another way you can do it: mixin template M() { export extern(C) pragma(mangle, "fun") void fun() {} } mixin M!(); which will work. -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #4 from Manu <turkeyman@gmail.com> --- Why are you comparing it to a struct with methods? mixin is not a structured object with methods, and there's no reason to think those methods should receive a context object and be mangled accordingly. mixin inserts material into the lexical scope, which in this case is the global scope. It's the closest thing we have to a macro. I understand the workaround, but this is broken. It's caught a couple of people now. It's embarrassing when people see something that doesn't work with no reasonable explanation; we have a lot of that, and there's only so many occurrences people can handle before their confidence is lost. Easy low-hanging fruit like this is worth fixing, and we can spend our confidence erosion budget on the real issues. -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #5 from Manu <turkeyman@gmail.com> --- > Using C mangling in a scope means there can be only one... Yes, and that's the entire point. That is how C is. Nobody would ever expect otherwise. -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #6 from Walter Bright <bugzilla@digitalmars.com> --- You can also use: enum M = "export extern(C) void fun() {}"; mixin(M); -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #7 from Manu <turkeyman@gmail.com> --- It's just one declaration among a bunch of other stuff that is inserted into the global scope, and it's the only declaration that doesn't 'work'. It shouldn't be separated from all its associated declarations, and it's super weird that that's required. Mixin templates into the global scope appear in every single reflection-driven application I've ever written. One part of that generated code is the entrypoint function which registers the modules contents with the module loader. Seriously, just fix this. It's a bug. -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #8 from Walter Bright <bugzilla@digitalmars.com> --- Template mixins are meant to be included multiple times. That's why the scope is part of the mangled name. -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #9 from Manu <turkeyman@gmail.com> --- A template mixin with an extern(C) function in it is obviously meant to be included at the global scope, why on earth would there be an extern(C) function in a template mixin otherwise? Especially an `extern` one. Nobody would be surprised by a link error complaining about multiple definitions of an extern(C) function; in fact, they'd be annoyed if it didn't. The pattern of a reflection template mixin placed at top-level is unbelievably common, and this code is common-sense for anyone trying to emit reflection-based data from a DLL. Lots of people don't use DLL's, so maybe it hasn't come up, but I use DLL's a lot. Seriously, the only conceivable useful thing you could do with an extern(C) function in a template mixin doesn't work. This is a bug. extern(C) means extern(C). There's no reason to re-interpret what extern(C) means in this one weird case. extern(C) specifies mangling and ABI, not mangling, or ABI, or maybe both. -- |
July 24, 2019 [Issue 20012] export inside mixin doesn't seem to work | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20012 --- Comment #10 from Walter Bright <bugzilla@digitalmars.com> --- (In reply to Manu from comment #9) > A template mixin with an extern(C) function in it is obviously meant to be > included at the global scope, why on earth would there be an extern(C) > function in a template mixin otherwise? Because there are uses for functions that follow the C ABI. Note that Microsoft C++ also distinguishes between C mangling and C ABI. Template mixins were designed so that boilerplate code can be inserted into many places. -- |
Copyright © 1999-2021 by the D Language Foundation