Thread overview
Why are extern(C/C++) definitions and references mangled differently in separately compiled modules?
Sep 06, 2019
Max Samukha
Sep 06, 2019
0xEAB
Sep 06, 2019
Max Samukha
Sep 06, 2019
Stefan Koch
Sep 06, 2019
Max Samukha
Sep 06, 2019
Max Samukha
Sep 06, 2019
Adam D. Ruppe
Sep 06, 2019
Max Samukha
Sep 07, 2019
Jacob Carlborg
Sep 07, 2019
Max Samukha
September 06, 2019
Consider the following two modules:

1. test.d:

module test;

import lib.a;

void main() {
    foo();
}


2. lib/a.d:

module lib.a;

extern(C) void foo() {}


When compiled separately (dmd -c lib/a.d; dmd test.d a.o), the function in 'a.o' is mangled as 'foo', but the reference in 'test.o' is mangled as '_D3lib1a3fooFZv', which leads to a link error. I would expect both of them to be either plain C mangling, or fully qualified D (better). What is the reason for current behavior?
September 06, 2019
On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote:
> Consider the following two modules:

What compiler version are you using?
September 06, 2019
On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote:
> Consider the following two modules:
>
> 1. test.d:
>
> module test;
>
> import lib.a;
>
> void main() {
>     foo();
> }
>
>
> 2. lib/a.d:
>
> module lib.a;
>
> extern(C) void foo() {}
>
>
> When compiled separately (dmd -c lib/a.d; dmd test.d a.o), the function in 'a.o' is mangled as 'foo', but the reference in 'test.o' is mangled as '_D3lib1a3fooFZv', which leads to a link error. I would expect both of them to be either plain C mangling, or fully qualified D (better). What is the reason for current behavior?

If that is happening you hit a bug.
It seems unlikely though.
September 06, 2019
On Friday, 6 September 2019 at 15:32:07 UTC, 0xEAB wrote:
> On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote:
>> Consider the following two modules:
>
> What compiler version are you using?

DMD64 D Compiler v2.088.0-1-g4011382ea, linux
September 06, 2019
On Friday, 6 September 2019 at 15:52:46 UTC, Stefan Koch wrote:
> On Friday, 6 September 2019 at 15:09:22 UTC, Max Samukha wrote:
>> Consider the following two modules:
>>
>> 1. test.d:
>>
>> module test;
>>
>> import lib.a;
>>
>> void main() {
>>     foo();
>> }
>>
>>
>> 2. lib/a.d:
>>
>> module lib.a;
>>
>> extern(C) void foo() {}
>>
>>
>> When compiled separately (dmd -c lib/a.d; dmd test.d a.o), the function in 'a.o' is mangled as 'foo', but the reference in 'test.o' is mangled as '_D3lib1a3fooFZv', which leads to a link error. I would expect both of them to be either plain C mangling, or fully qualified D (better). What is the reason for current behavior?
>
> If that is happening you hit a bug.
> It seems unlikely though.

Could you elaborate a bit? How should extern(C/C++) definitions be mangled - fully qualified or not, and why is the reference to extern(C/C++) D-mangled? The spec seems to say nothing about it.

September 06, 2019
On Friday, 6 September 2019 at 16:55:31 UTC, Max Samukha wrote:
> On Friday, 6 September 2019 at 15:52:46 UTC, Stefan Koch wrote:

>> If that is happening you hit a bug.
>> It seems unlikely though.
>
> Could you elaborate a bit? How should extern(C/C++) definitions be mangled - fully qualified or not, and why is the reference to extern(C/C++) D-mangled? The spec seems to say nothing about it.

Ok, I have figured it out. There was 'a.di' file along with 'a.d' in the same directory, with a definition of extern(D) foo. That file was silently imported by the compiler (probably, a bug). Thank you for your attention.



September 06, 2019
On Friday, 6 September 2019 at 17:42:08 UTC, Max Samukha wrote:
> That file was silently imported by the compiler (probably, a bug).

That's by design - the automatic module import lookups actually always look for .di file first, then .d files.
September 06, 2019
On Friday, 6 September 2019 at 17:54:51 UTC, Adam D. Ruppe wrote:
> On Friday, 6 September 2019 at 17:42:08 UTC, Max Samukha wrote:
>> That file was silently imported by the compiler (probably, a bug).
>
> That's by design - the automatic module import lookups actually always look for .di file first, then .d files.

Is there any practical use of having identically named .d and .di alongside?
September 07, 2019
On 2019-09-06 21:03, Max Samukha wrote:

> Is there any practical use of having identically named .d and .di alongside?

Same as in C/C++. This allows you to have a header file if you want to distribute a closed source library.

-- 
/Jacob Carlborg
September 07, 2019
On Saturday, 7 September 2019 at 13:01:38 UTC, Jacob Carlborg wrote:
> On 2019-09-06 21:03, Max Samukha wrote:
>
>> Is there any practical use of having identically named .d and .di alongside?
>
> Same as in C/C++. This allows you to have a header file if you want to distribute a closed source library.

I know, but I have never seen a D project that would generate headers into the source directory. C++ requires headers for sharing declarations with other translation units in the project, even if the headers are not intended for distribution. That is why having headers alongside implementations is a common case there. D doesn't require that.

Anyway, that's a minor concern. Thank you.