Difference between revisions of "DIP61"

From D Wiki
Jump to: navigation, search
(initial edit)
 
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{| class="wikitable"
 
{| class="wikitable"
 
!Title:
 
!Title:
!'''DIP Template'''
+
!'''Add namespace scopes to support referencing external C++ symbols in C++ namespaces'''
 
|-
 
|-
 
|DIP:
 
|DIP:
Line 10: Line 10:
 
|-
 
|-
 
|Status:
 
|Status:
|Draft
+
|Implemented
 
|-
 
|-
 
|Created:
 
|Created:
Line 22: Line 22:
 
|-
 
|-
 
|Links:
 
|Links:
|[[DIP61/Archive]] — [http://www.digitalmars.com/d/archives/digitalmars/D/announce/dmd_1.046_and_2.031_releases_16320.html#N16448 NG discussion that triggered the DIP]
+
|[[DIP61/Archive]]
— [http://www.digitalmars.com/d/archives/digitalmars/D/new_DIP1_DIP_Template_92908.html NG announcement and discussion]
+
— [http://forum.dlang.org/post/lhi1lt$269h$1@digitalmars.com NG discussion that triggered the DIP]
 +
— [http://forum.dlang.org/post/ljfue4$11dk$1@digitalmars.com NG announcement and discussion]
 +
— [http://forum.dlang.org/post/ljjnaa$187r$1@digitalmars.com more NG discussion]
 +
- [https://github.com/D-Programming-Language/dmd/pull/3517 Pull Request]
 
|}
 
|}
  
 
== Abstract ==
 
== Abstract ==
Add support for namespaces.
+
Add ability to reference from D C++ symbols that are in C++ namespaces.
  
 
== Rationale ==
 
== Rationale ==
 
Best practices in C++ code increasingly means putting functions and declarations in namespaces. Currently,
 
Best practices in C++ code increasingly means putting functions and declarations in namespaces. Currently,
 
there is no support in D to call C++ functions in namespaces. The primary issue is that the name mangling
 
there is no support in D to call C++ functions in namespaces. The primary issue is that the name mangling
doesn't match.
+
doesn't match. Need a simple and straightforward method of indicating namespaces.
  
 
== Description ==
 
== Description ==
 
A namespace scope creates a scope with a name, and inside that scope all declarations become part of the
 
A namespace scope creates a scope with a name, and inside that scope all declarations become part of the
namespace scope.
+
namespace scope. This involves the addition of a small amount of new grammar.
 +
Compiler changes are expected to be minor. The change is additive and should not impact any existing code.
 +
 
 +
The namespace is identified by an identifier following the C++ in extern(C++). Nested namespaces can be
 +
specified using . to separate them.
  
 
== Usage ==
 
== Usage ==
  
namespace MyNamespace { int foo(); }
+
<syntaxhighlight lang="d">
 +
extern (C++, MyNamespace) { int foo(); }
 +
</syntaxhighlight>
 +
 
 +
creates a namespace named "MyNamespace". As is currently the case,
 +
 
 +
<syntaxhighlight lang="d">
 +
extern (C++) { int foo(); }
 +
</syntaxhighlight>
 +
 
 +
does not create a namespace.
 +
 
 +
The following declarations are all equivalent:
 +
 
 +
<syntaxhighlight lang="d">
 +
extern (C++) { extern (C++, N) { extern (C++, M) { int foo(); }}}
 +
extern (C++, N.M) { int foo(); }
 +
extern (C++, N) { extern (C++) { extern (C++, M) { int foo(); }}}
 +
</syntaxhighlight>
  
 
Namespaces can be nested. Declarations in the namespace can be accessed without qualification in the enclosing
 
Namespaces can be nested. Declarations in the namespace can be accessed without qualification in the enclosing
 
scope if there is no ambiguity. Ambiguity issues can be resolved by adding the namespace qualifier:
 
scope if there is no ambiguity. Ambiguity issues can be resolved by adding the namespace qualifier:
  
namespace N { int foo(); int bar(); }
+
<syntaxhighlight lang="d">
namespace M { long foo(); }
+
extern (C++, N) { int foo(); int bar(); }
 +
extern (C++, M) { long foo(); }
  
 
bar(); // ok
 
bar(); // ok
Line 52: Line 78:
 
N.foo(); // ok
 
N.foo(); // ok
 
N.bar(); // ok
 
N.bar(); // ok
 +
</syntaxhighlight>
  
 
Name lookup rules are the same as for mixin templates.
 
Name lookup rules are the same as for mixin templates.
  
== NG Announcement ==
+
Unlike C++, namespaces in D will be 'closed' meaning that new declarations cannot be inserted into a namespace after the closing }. C++ Argument Dependent Lookup (aka "Koenig Lookup") will not be supported.
When posting the DIP announcement to the NG, please copy the abstract, so people can easily know what is it about and follow the link if they are interested.
 
 
 
  
 +
== Grammar Change ==
 +
<i>LinkageAttribute</i>:
 +
    <b>extern</b> <b>(</b> <i>identifier</i> <b>)</b>
 +
    <b>extern</b> <b>(</b> <i>identifier</i> <b>++</b> <b>)</b>
 +
    <b>extern</b> <b>(</b> <i>identifier</i> <b>++</b> <b>,</b> <i>identifier</i> ( <b>.</b> <i>identifier</i> )* <b>)</b>
 
== Copyright ==
 
== Copyright ==
 
This document has been placed in the Public Domain.
 
This document has been placed in the Public Domain.
  
 
[[Category: DIP]]
 
[[Category: DIP]]

Latest revision as of 06:07, 17 July 2014

Title: Add namespace scopes to support referencing external C++ symbols in C++ namespaces
DIP: 61
Version: 1
Status: Implemented
Created: 2014-04-26
Last Modified: 2014-04-26
Author: Walter Bright
Links: DIP61/Archive

NG discussion that triggered the DIPNG announcement and discussionmore NG discussion - Pull Request

Abstract

Add ability to reference from D C++ symbols that are in C++ namespaces.

Rationale

Best practices in C++ code increasingly means putting functions and declarations in namespaces. Currently, there is no support in D to call C++ functions in namespaces. The primary issue is that the name mangling doesn't match. Need a simple and straightforward method of indicating namespaces.

Description

A namespace scope creates a scope with a name, and inside that scope all declarations become part of the namespace scope. This involves the addition of a small amount of new grammar. Compiler changes are expected to be minor. The change is additive and should not impact any existing code.

The namespace is identified by an identifier following the C++ in extern(C++). Nested namespaces can be specified using . to separate them.

Usage

extern (C++, MyNamespace) { int foo(); }

creates a namespace named "MyNamespace". As is currently the case,

extern (C++) { int foo(); }

does not create a namespace.

The following declarations are all equivalent:

extern (C++) { extern (C++, N) { extern (C++, M) { int foo(); }}}
extern (C++, N.M) { int foo(); }
extern (C++, N) { extern (C++) { extern (C++, M) { int foo(); }}}

Namespaces can be nested. Declarations in the namespace can be accessed without qualification in the enclosing scope if there is no ambiguity. Ambiguity issues can be resolved by adding the namespace qualifier:

extern (C++, N) { int foo(); int bar(); }
extern (C++, M) { long foo(); }

bar(); // ok
foo(); // error, ambiguous
N.foo(); // ok
N.bar(); // ok

Name lookup rules are the same as for mixin templates.

Unlike C++, namespaces in D will be 'closed' meaning that new declarations cannot be inserted into a namespace after the closing }. C++ Argument Dependent Lookup (aka "Koenig Lookup") will not be supported.

Grammar Change

LinkageAttribute:
    extern ( identifier )
    extern ( identifier ++ )
    extern ( identifier ++ , identifier ( . identifier )* )

Copyright

This document has been placed in the Public Domain.