April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Mon, 28 Apr 2014 10:00:56 -0400, Ola Fosheim Grøstad <ola.fosheim.grostad+dlang@gmail.com> wrote: > On Monday, 28 April 2014 at 13:47:43 UTC, Steven Schveighoffer wrote: >> Not ok. This is like having 2 definitions for the same function, linker will not accept that. > > No. It is like having 2 matching type declarations. The implementation is defined in the C++ source code and is represented as one C++ object/lib file to the linker. The linker will happily accept that. Oh sorry, in my head, I was sure they each had implementations ;) Yeah, I think that should work just fine. I see now where your objection is. I think either the rule needs to be better explained, or that it is incorrect. -Steve |
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Monday, 28 April 2014 at 14:08:56 UTC, Steven Schveighoffer wrote:
> I see now where your objection is. I think either the rule needs to be better explained, or that it is incorrect.
I think so too, because if my undestanding is correct then it will discourage writing libs in mixed D/C++ and encourage writing libs in pure C++.
Basically turning D into an application level language (on the level of Objective-C so to speak)?
|
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sun, 27 Apr 2014 15:54:51 -0400, Walter Bright <newshound2@digitalmars.com> wrote:
> http://wiki.dlang.org/DIP61
I think there is a big problem with name lookup here.
Consider this code:
module foo;
void func() {}
module bar;
extern(C) func();
module prog;
import foo;
import bar;
void main()
{
func(); // error
foo.func(); // ok
bar.func(); // ok, uses C binding (no name mangling)
}
In this case, even though the C function is not mangled or in any other namespace, the module can be used for unambiguous calling.
But in your proposal, the name qualifiers could be either C++ namespaces or D modules. This presents an unnecessary ambiguity.
e.g.
module foo;
void func() {}
module bar;
extern(C++, foo) void func(); // foo::func in C++ land
module prog;
import foo;
import bar;
void main()
{
func(); // error
foo.func(); // ALSO error
bar.func(); // Not error, BUT it's actually calling foo::func from C++ land!
}
I think we cannot change name lookup rules for C++ symbols, because the D module system already owns those.
An alternative is that you could create an alternate way to disambiguate. Let's pick a strawman called _cpp, just to illustrate:
void main()
{
func(); // error still
foo.func(); // calls D's foo module's func
bar.func(); // calls D's bar module's func (defined as foo::func)
_cpp.func(); // error, _cpp denotes we are using namespace qualifiers, and there is no global C++ func
_cpp.foo.func(); // calls D's bar module's func.
bar._cpp.foo.func(); // ditto
}
Really, _cpp could be anything. But I think hijacking D's module qualifiers does not help. To make things seamless, you could make it ::, but I know many people have objections to that.
-Steve
|
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Mon, 28 Apr 2014 10:27:19 -0400, Steven Schveighoffer wrote:
> On Sun, 27 Apr 2014 15:54:51 -0400, Walter Bright <newshound2@digitalmars.com> wrote:
>
>> http://wiki.dlang.org/DIP61
>
> I think there is a big problem with name lookup here.
>
> Consider this code:
>
> module foo;
>
> void func() {}
>
> module bar;
>
> extern(C) func();
>
> module prog;
>
> import foo;
> import bar;
>
> void main()
> {
> func(); // error foo.func(); // ok bar.func(); // ok, uses C binding
> (no name mangling)
> }
>
> In this case, even though the C function is not mangled or in any other namespace, the module can be used for unambiguous calling.
>
> But in your proposal, the name qualifiers could be either C++ namespaces or D modules. This presents an unnecessary ambiguity.
>
> e.g.
>
> module foo;
>
> void func() {}
>
> module bar;
>
> extern(C++, foo) void func(); // foo::func in C++ land
>
> module prog;
>
> import foo;
> import bar;
>
> void main()
> {
> func(); // error foo.func(); // ALSO error bar.func(); // Not error,
> BUT it's actually calling foo::func from C++
> land!
> }
>
> I think we cannot change name lookup rules for C++ symbols, because the D module system already owns those.
>
> An alternative is that you could create an alternate way to
> disambiguate.
> Let's pick a strawman called _cpp, just to illustrate:
>
> void main()
> {
> func(); // error still foo.func(); // calls D's foo module's func
> bar.func(); // calls D's bar module's func (defined as foo::func)
> _cpp.func(); // error, _cpp denotes we are using namespace
> qualifiers,
> and there is no global C++ func
> _cpp.foo.func(); // calls D's bar module's func.
> bar._cpp.foo.func(); // ditto
> }
>
> Really, _cpp could be anything. But I think hijacking D's module qualifiers does not help. To make things seamless, you could make it ::, but I know many people have objections to that.
>
> -Steve
why not import _cpp = bar; ?
|
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Byron | On Mon, 28 Apr 2014 10:37:36 -0400, Byron <byron.heads@gmail.com> wrote:
>
> why not import _cpp = bar; ?
That doesn't help. foo.func() is still ambiguous. With this proposal, you have hijacked the meaning of namespace lookup. When I say x.y.z, it doesn't just mean look for symbol z in module x/y.d, it can also mean to look for symbol z in C++ namespace x::y. This was not the case with C binding, which continued to use D modules for symbol lookup.
Consider that a boatload of C++ code is named std::something. Now, std.string has an ambiguous meaning wherever it is used!
-Steve
|
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sun, 27 Apr 2014 12:54:51 -0700, Walter Bright wrote:
> http://wiki.dlang.org/DIP61
Would nesting imported namespaces work?
lib/package.d
public
export(C++, a) {
public import lib.b;
}
lib/b.d
export(C++, b) {
void foo();
}
main.d
import lib;
a.b.foo();
|
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Mon, 28 Apr 2014 10:45:14 -0400, Steven Schveighoffer wrote:
> On Mon, 28 Apr 2014 10:37:36 -0400, Byron <byron.heads@gmail.com> wrote:
>
>
>> why not import _cpp = bar; ?
>
> That doesn't help. foo.func() is still ambiguous. With this proposal, you have hijacked the meaning of namespace lookup. When I say x.y.z, it doesn't just mean look for symbol z in module x/y.d, it can also mean to look for symbol z in C++ namespace x::y. This was not the case with C binding, which continued to use D modules for symbol lookup.
>
> Consider that a boatload of C++ code is named std::something. Now, std.string has an ambiguous meaning wherever it is used!
>
> -Steve
bar is renamed, thus you have to access via _cpp.[namespace] renames were added to prevent hijacking.
|
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Byron | On Mon, 28 Apr 2014 10:50:09 -0400, Byron <byron.heads@gmail.com> wrote:
> On Mon, 28 Apr 2014 10:45:14 -0400, Steven Schveighoffer wrote:
>
>> On Mon, 28 Apr 2014 10:37:36 -0400, Byron <byron.heads@gmail.com> wrote:
>>
>>
>>> why not import _cpp = bar; ?
>>
>> That doesn't help. foo.func() is still ambiguous. With this proposal,
>> you have hijacked the meaning of namespace lookup. When I say x.y.z, it
>> doesn't just mean look for symbol z in module x/y.d, it can also mean to
>> look for symbol z in C++ namespace x::y. This was not the case with C
>> binding, which continued to use D modules for symbol lookup.
>>
>> Consider that a boatload of C++ code is named std::something. Now,
>> std.string has an ambiguous meaning wherever it is used!
>>
>> -Steve
>
> bar is renamed, thus you have to access via _cpp.[namespace]
> renames were added to prevent hijacking.
That renames the bar module, but not the foo C++ namespace, which can be assumed when calling foo.func.
In reality, you could "fix" the situation by renaming the foo D module, and then foo.func would unambiguously refer to bar's func :)
Another alternative fix would be to allow renaming C++ namespaces. I strongly recommend against that. The better alternative is to reserve qualified name lookup to D modules alone. Adding a mechanism that is possibly ugly, but that does NOT conflict with module lookup, in order to disambiguate C++ symbols is fine.
-Steve
|
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Byron | On Mon, 28 Apr 2014 10:46:33 -0400, Byron <byron.heads@gmail.com> wrote: > On Sun, 27 Apr 2014 12:54:51 -0700, Walter Bright wrote: > >> http://wiki.dlang.org/DIP61 > > Would nesting imported namespaces work? > > lib/package.d > public > export(C++, a) { > public import lib.b; > > } > > > lib/b.d > export(C++, b) { > void foo(); > } > > main.d > import lib; > a.b.foo(); Most definitely no. When the compiler builds b.d, he has no idea it's imported from inside another namespace! We don't want #include-style issues. -Steve |
April 28, 2014 Re: DIP61: redone to do extern(C++,N) syntax | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Monday, 28 April 2014 at 14:54:17 UTC, Steven Schveighoffer wrote:
> Adding a mechanism that is possibly ugly, but that does NOT conflict with module lookup, in order to disambiguate C++ symbols is fine.
Requiring C++ identifiers to be fully qualified with "::" would solve that and encourage writing thin idiomatic D wrappers on top of C++ libs.
(and cause a lot of complaints from C++ programmers :-)
|
Copyright © 1999-2021 by the D Language Foundation