digitalmars.D - Why extern variables and functions within template/struct/class have a
- Igor Stepanov (15/15) May 07 2013 Is it correct?
- Igor Stepanov (8/8) May 07 2013 May be I need to fix that issue? What about functions?
- Andrej Mitrovic (11/18) May 08 2013 No. For one example, internal extern(C) functions can be used for
- Dicebot (4/5) May 08 2013 Suck code is invalid in C++ and for a good reason. I'd really
- Andrej Mitrovic (3/8) May 08 2013 Sorry, I forgot I was actually thinking about *static* extern(C)
- Dicebot (3/14) May 08 2013 static methods are illegal in C++ with extern(C) too. As well as
- Andrej Mitrovic (2/3) May 08 2013 I don't see why. They're useful in D anyway.
- Dicebot (6/9) May 08 2013 Because they have namespace (class namespace) and can't be
- Andrej Mitrovic (3/8) May 08 2013 Right, you may not be able to statically link with it but it's still a
- Dicebot (12/22) May 08 2013 Well, that is one of rather inconvenient issues with D handling
- Andrej Mitrovic (11/15) May 08 2013 Yeah.
- Dicebot (19/35) May 08 2013 That may work as temporarily solution but I really think it is
- Andrej Mitrovic (6/8) May 08 2013 Don't worry, and I agree with you. But I think it's probably too late
- Igor Stepanov (17/29) May 09 2013 I've undestood, that function mangling is a difficult issue.
Is it correct? When I wrote next code: template Extern(string s) { mixin("static extern(C) extern int "~s~";"~ "alias Extern = "~s~";"); } void main() { writeln(&Extern!("xxx")); } I get error message "undefined reference to `_D1a24__T6ExternVAyaa3_787878Z3xxxi'", when I expect to get "undefined reference to `xxx'"? Is it error?
May 07 2013
May be I need to fix that issue? What about functions? struct Foo { extern(C) void bar() { } } Is it good to set bar mangling to "bar"?
May 07 2013
On 5/7/13, Igor Stepanov <wazar.leollone yahoo.com> wrote:struct Foo { extern(C) void bar() { } } Is it good to set bar mangling to "bar"?No. For one example, internal extern(C) functions can be used for callbacks. You wouldn't want linking to fail if you have this code: struct A { extern(C) void callback() { } } struct B { extern(C) void callback() { } }
May 08 2013
On Wednesday, 8 May 2013 at 09:09:34 UTC, Andrej Mitrovic wrote:...Suck code is invalid in C++ and for a good reason. I'd really expect D to refuse to compile extern(C) functions it can't possibly mangle correctly.
May 08 2013
On 5/8/13, Dicebot <m.strashun gmail.com> wrote:On Wednesday, 8 May 2013 at 09:09:34 UTC, Andrej Mitrovic wrote:Sorry, I forgot I was actually thinking about *static* extern(C) functions. I'm not sure about methods....Suck code is invalid in C++ and for a good reason. I'd really expect D to refuse to compile extern(C) functions it can't possibly mangle correctly.
May 08 2013
On Wednesday, 8 May 2013 at 09:22:52 UTC, Andrej Mitrovic wrote:On 5/8/13, Dicebot <m.strashun gmail.com> wrote:static methods are illegal in C++ with extern(C) too. As well as any namespaced function. Or any function that has overloads.On Wednesday, 8 May 2013 at 09:09:34 UTC, Andrej Mitrovic wrote:Sorry, I forgot I was actually thinking about *static* extern(C) functions. I'm not sure about methods....Suck code is invalid in C++ and for a good reason. I'd really expect D to refuse to compile extern(C) functions it can't possibly mangle correctly.
May 08 2013
On 5/8/13, Dicebot <m.strashun gmail.com> wrote:static methods are illegal in C++ with extern(C) too.I don't see why. They're useful in D anyway.
May 08 2013
On Wednesday, 8 May 2013 at 09:46:00 UTC, Andrej Mitrovic wrote:On 5/8/13, Dicebot <m.strashun gmail.com> wrote:Because they have namespace (class namespace) and can't be mangled according to C rules. Exactly your example. You can't have two "foo"'s there but any other naming scheme IS NOT C mangling but some weird abomination that pretends to be it. Thus it is a compile-time error.static methods are illegal in C++ with extern(C) too.I don't see why. They're useful in D anyway.
May 08 2013
On 5/8/13, Dicebot <m.strashun gmail.com> wrote:Because they have namespace (class namespace) and can't be mangled according to C rules. Exactly your example. You can't have two "foo"'s there but any other naming scheme IS NOT C mangling but some weird abomination that pretends to be it. Thus it is a compile-time error.Right, you may not be able to statically link with it but it's still a calling convention, so it's useful (for callbacks).
May 08 2013
On Wednesday, 8 May 2013 at 09:56:14 UTC, Andrej Mitrovic wrote:On 5/8/13, Dicebot <m.strashun gmail.com> wrote:Well, that is one of rather inconvenient issues with D handling of emitting symbols (this one kind of inherited from C++). extern(X) defines both mangling and calling convention. You can't have those separately now. Saying in one case it is both mangling and ABI and in other one it is only ABY smells like broken specification/implementation. Actually I remember discussing this with Volt language team recently. Currently relation between D type system and emitted symbols is not that well-defined in spec and this is one of many cases where it causes problems. I don't think it can be fixed without some sort of overhaul.Because they have namespace (class namespace) and can't be mangled according to C rules. Exactly your example. You can't have two "foo"'s there but any other naming scheme IS NOT C mangling but some weird abomination that pretends to be it. Thus it is a compile-time error.Right, you may not be able to statically link with it but it's still a calling convention, so it's useful (for callbacks).
May 08 2013
On 5/8/13, Dicebot <m.strashun gmail.com> wrote:Well, that is one of rather inconvenient issues with D handling of emitting symbols (this one kind of inherited from C++). extern(X) defines both mangling and calling convention. You can't have those separately now.Yeah. I suppose the ideal situation would be to have extern(C) follow strict C mangling and calling convention (meaning no mangling for nested extern(C) symbols), and have a separate linkage(C) feature to be used when we want to set the linkage of a symbol (well, it's probably only useful for functions) but let the compiler mangle it any way it wants to (to avoid any symbol clashes). There's a pull request somewhere which enables setting custom mangle names for symbols, so we'll at least have the flexibility in picking symbol names that we need.
May 08 2013
On Wednesday, 8 May 2013 at 10:28:40 UTC, Andrej Mitrovic wrote:I suppose the ideal situation would be to have extern(C) follow strict C mangling and calling convention (meaning no mangling for nested extern(C) symbols), and have a separate linkage(C) feature to be used when we want to set the linkage of a symbol (well, it's probably only useful for functions) but let the compiler mangle it any way it wants to (to avoid any symbol clashes). There's a pull request somewhere which enables setting custom mangle names for symbols, so we'll at least have the flexibility in picking symbol names that we need.That may work as temporarily solution but I really think it is just hiding forest behind the trees. That part of language needs some serious attention at one point, not just few pull requests. To define all possible linkage modifiers. To define possible mangling modifiers. To define symbol visibility. For example, do you remember discussion about classes and provable method (non-)virtuality? Which ended at a conclusion that it can't work because class can be inherited from anywhere, for example from called dll. Funny thing we have an "export" as a protection attribute: "Export means that any code outside the executable can access the member. Export is analogous to exporting definitions from a DLL." Cool. Problem is access/visibility rules for symbols that are _not_ marked with "export" is not defined and looking and generated binaries is not enforced in any way by dmd at least. Which makes export kind of joke. Well, pardon me, I probably have exceeded my allowed daily rant limit :)
May 08 2013
On 5/8/13, Dicebot <m.strashun gmail.com> wrote:Well, pardon me, I probably have exceeded my allowed daily rant limit :)Don't worry, and I agree with you. But I think it's probably too late to actually change what a linkage specifier does for nested symbols. We might end up getting duplicate symbol definition errors (hello Optlink..) in completely unrelated libraries if mangling changes for these symbols.
May 08 2013
On Wednesday, 8 May 2013 at 19:14:14 UTC, Andrej Mitrovic wrote:On 5/8/13, Dicebot <m.strashun gmail.com> wrote:I've undestood, that function mangling is a difficult issue. But what about extern variables? Obviously, when user write ("extern(C) extern int var;"), he want to get extern variable with C mangling. Another way: get second parameter (symbol name) to extern attribute. E.g. extern(C, " FOO ")void FOO(int); //have C linkage and FOO mangling extern(C)void FOO2(int); //have C linkage and C (or D, if FOO2 is local symbol) mangling extern("__FOO__") void FOO(int); //have D or System linkage and "__FOO__" mangling However, I would like to mangling argument of extern attribute will be evaluatable form any string expression. enum MANGLING = " M "; extern(D, MANGLING) int boo();Well, pardon me, I probably have exceeded my allowed daily rant limit :)Don't worry, and I agree with you. But I think it's probably too late to actually change what a linkage specifier does for nested symbols. We might end up getting duplicate symbol definition errors (hello Optlink..) in completely unrelated libraries if mangling changes for these symbols.
May 09 2013