Topic: extern inlines; draft update status


Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 8 Mar 1995 19:16:50 GMT
Raw View
In article <D4uMy2.BFr@ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
[..]
|> >              "using" and "using namespace" should be transitive.
|>
|>  They are. But qualification does not commute with them.
|> It is not an oversight. Quite deliberately the rule was that for
|> Y::x we require x to be a member of Y. (There are arguments
|> for both rules)
[..]
|> >What about
|> >
|> > namespace X { int x; }
|> > namespace Y { using X::x; }
|> > Y::x++; // error ???
|>
|>  No error. "x" is a name of Y.
[..]
|>                              A using declaration as above
|> is a declaration of x. A using directive (using namespace) is not.

Ah, one more example of the subtile difference of using-declaration
and using-directive.

IMHO a rule like:

 The entity that is denoted by `QUAL::NAME', is the same entity
 that is denoted by `NAME' inside the scope of QUAL.
 By the using-declaration `using QUAL::NAME'
 `NAME' denotes the same entity that `QUAL::NAME' denotes.
 By the using-directive 'using namespace QUAL'
 `NAME' denotes the same entity that `QUAL::NAME' denotes
 if NAME denotes something in QUAL.

would follow the principle of least surprise. For humans, it is rather
less than more compilcated than the current rule:

 The entity that is denoted by `QUAL::NAME', is the member
 NAME of the namespace/class QUAL.
 By the using-declaration `using QUAL::NAME' the member NAME of the
 current scope is introduced, denoting the same entity as `QUAL::NAME'.
 By the using-directive `using namespace QUAL' NAME inside
 the current namespace denotes the member NAME of QUAL
 if NAME is a member of QUAL.


|>  We do not have that much experience with namespaces so
|> any comments from users will be listened to.

I just can't resist such an invitation ;-)


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Fri, 3 Mar 1995 05:22:49 GMT
Raw View
In article <3ildfb$psg@hpsystem1.informatik.tu-muenchen.de>,
Ulf Schuenemann <schuenem@Informatik.TU-Muenchen.DE> wrote:
>
>In article <D45Azw.3ru@ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>[..]
>|>  It says -- AT PRESENT -- that ::x refers ONLY to the
>|> global, and never to the unnamed namespace member, which is
>|> consistent with
>|>
>|>  namespace X { int x; }
>|>  namespace Y { using namespace X; }
>|>  Y::x++; // error
>|>
>|> However, several issues regarding this have been raised and
>|> Bjarne has suggested changing the rule so that X::x++
>                                                  ^^^^^^
>I suppose you meant ".. so that Y::x++ would work and referes to X::x++".

 Woops. Sorry.
>
>|> would work here and so that
>|>
>|>  ::x
>|>
>|> can refer to an x in an unnamed namespace.
>
>I don't see how Bjarn's suggestion would make any difference in this case.
>Well, if you think of an implicit "using namespace UNIQUE;" it would work.

 That is the _specification_.

>This would be a generalisation from [r.3.3.1.3] "A name from an unnamed
>namespace can be accessed without qualification ..."

 I apologise that while I can refer the Working Paper,
you are stuck with the ARM. The ARM is not as up to date,
nor is Bjarne's explanation therein as precise as that of the
WP (otherwise it would be the WP :-)

 Both are probably sloppy, but the ARM is sloppier.
>
>|>                                            I do not know if this
>|> suggestion will turn into a proposal which will be accepted.
>|>

>Yes, the suggestion "Y::x++ referes to X::x++" is a good idea. To be
>honest, I can't understand why it does not work now. To me it looks
>like an oversight. "using" and "using namespace" should be transitive.

 They are. But qualification does not commute with them.
It is not an oversight. Quite deliberately the rule was that for
Y::x we require x to be a member of Y. (There are arguments
for both rules)

 The point is that after some consideration, and
feedback from users, Bjarne now believes we should reconsider
this decision.

 We do not have that much experience with namespaces so
any comments from users will be listened to. Changing an already
made decision should not be taken lightly.
>
>What about
>
> namespace X { int x; }
> namespace Y { using X::x; }
> Y::x++; // error ???

 No error. "x" is a name of Y. As if:

 namespace Y {
  int &x = X::x;
 }

had been written. Had "x" been a type,

 namespace Y {
  typedef X::x x;
 }

would have been equivalent.  A using declaration as above
is a declaration of x. A using directive (using namespace) is not.

>instead of the deprecated access-declaration. (Depending on what exactly
>[r.3.3.1.3 Classes] "For purpose of namelookup, the scope of a class is
>a namespace. The scope of a derived class is nested in the scope of
>each of its base classes." means in this case).

 I advise you put a big fat red line through that sentence.
The idea has _not_ been carried through into the normative rules
of the Working Paper.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: George Flanagin <aniceman@thuridion.com>
Date: 3 Mar 1995 18:21:15 GMT
Raw View
schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) wrote:
>  All unnamed namespaces within the same namespace N of a compiliation
>  unit are treated as one namespace, "the unnamed namespace of N,"
>  and treated as if it had a name that is unique in a program.

-g-> Isn't this the "blank common" solution from FORTRAN 66/77?

George Flanagin
aniceman@thuridion.com




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 24 Feb 1995 20:16:02 GMT
Raw View

IMHO the whole unnamed-namespace-thing [r.3.3.1.3] is a bit unclear:

 All unnamed namespaces within a compiliation unit are treated
 as one namespace, "the unnamed namespace," and treated as if
 it had a name that is unique in a program.

IMO this would imply that

 namespace {  // this is an unnamed namespace
  int x; // defines "the unnamed namespace"::x
 };
 namespace A {
     namespace {  // this is also an unnamed namespace
  int x; // ERROR redefinition of
    // "the unnamed namespace"::x
     };
 };

I don't believe that this was intended. I would prefere something like:

 All unnamed namespaces within the same namespace N of a compiliation
 unit are treated as one namespace, "the unnamed namespace of N,"
 and treated as if it had a name that is unique in a program.


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Sun, 26 Feb 1995 05:51:37 GMT
Raw View
In article <3ileq2$qan@hpsystem1.informatik.tu-muenchen.de>,
Ulf Schuenemann <schuenem@Informatik.TU-Muenchen.DE> wrote:
>
>
>IMHO the whole unnamed-namespace-thing [r.3.3.1.3] is a bit unclear:
>
> All unnamed namespaces within a compiliation unit are treated
> as one namespace, "the unnamed namespace," and treated as if
> it had a name that is unique in a program.
>

 Thats WRONG. I fixed that when I wrote the original
text from the Working Paper, which was edited by the Editor
Andrew Koenig -- as far as I know he preserved the correct
mechanism.

>IMO this would imply that
>
> namespace {  // this is an unnamed namespace
>  int x; // defines "the unnamed namespace"::x
> };
> namespace A {
>     namespace {  // this is also an unnamed namespace
>  int x; // ERROR redefinition of
>    // "the unnamed namespace"::x
>     };
> };
>
>I don't believe that this was intended.

 Remember Bjarne writes for programmers, the rules
are "waffly" to give you an idea. They're not complete or
precise -- otherwise there would be no need for Standardisation.

 If you want to find the precise rules, you need
the Working Paper.

>I would prefere something like:
>
> All unnamed namespaces within the same namespace N of a compiliation
> unit are treated as one namespace, "the unnamed namespace of N,"
> and treated as if it had a name that is unique in a program.

 That is correct. In fact, the unnamed namespace is always
named "UNIQUE" where "UNIQUE" varies between compilation
units but NOT within them. I hope you can see why invariant naming
within a translation unit always works correctly to group
the multiple extents of a namespace togther.

 [Hint. It works the same for a named namespace :-)


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 24 Feb 1995 19:53:15 GMT
Raw View
In article <D45Azw.3ru@ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
[..]
|>  It says -- AT PRESENT -- that ::x refers ONLY to the
|> global, and never to the unnamed namespace member, which is
|> consistent with
|>
|>  namespace X { int x; }
|>  namespace Y { using namespace X; }
|>  Y::x++; // error
|>
|> However, several issues regarding this have been raised and
|> Bjarne has suggested changing the rule so that X::x++
                                                  ^^^^^^
I suppose you meant ".. so that Y::x++ would work and referes to X::x++".

|> would work here and so that
|>
|>  ::x
|>
|> can refer to an x in an unnamed namespace.

I don't see how Bjarn's suggestion would make any difference in this case.
Well, if you think of an implicit "using namespace UNIQUE;" it would work.
This would be a generalisation from [r.3.3.1.3] "A name from an unnamed
namespace can be accessed without qualification ..."

|>                                            I do not know if this
|> suggestion will turn into a proposal which will be accepted.
|>
|> Any comments here about it might be read by committee members
|> including Bjarne. I'm not certain, but the suggestion seems to
|> be workable in principle. Is it a good idea?

Yes, the suggestion "Y::x++ referes to X::x++" is a good idea. To be
honest, I can't understand why it does not work now. To me it looks
like an oversight. "using" and "using namespace" should be transitive.

What about

 namespace X { int x; }
 namespace Y { using X::x; }
 Y::x++; // error ???

If it is an error, that would break the usage of "using <inherited-member>;"
instead of the deprecated access-declaration. (Depending on what exactly
[r.3.3.1.3 Classes] "For purpose of namelookup, the scope of a class is
a namespace. The scope of a derived class is nested in the scope of
each of its base classes." means in this case).


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Mon, 20 Feb 1995 09:23:46 GMT
Raw View
fenster@ground.cs.columbia.edu (Sam Fenster) writes:

>C'monnn, be a sport, puhleeeez?  Be helpful?

I'm sorry - I _was_ trying to be helpful.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au
all [L] (programming_language(L), L \= "Mercury") => better("Mercury", L) ;-)




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 21 Feb 1995 16:17:52 GMT
Raw View
In article <D45Azw.3ru@ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
[..]
|>  IMHO: The simplest rule is:
|>
|>  ALL symbols have external linkage. ALL of them.
|>
|>  IF the full-name of the symbol containes a UNIQUE
|>  part, then the name ALSO has internal linkage.
[..]

Usually 'intern' is thought of as the opposite of 'extern'. Whereas
'interal linkage' is a special case of 'external linkage'. To prevent
confusion it might be clearer to use other terms in the standard to
describe linkage.
Unfortunatly the meaning of 'extern linkage' is predefined by the
keyword "extern" used for forward-declaration of any names/symbols.
So we should find a better name for 'internal linkage' that is unique
per translation-unit and thus private (internal) to it. How about
'unique', 'module' or 'private' ?

 long name: external linkage unique external linkage
 short name: linkage   unique linkage


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Fri, 17 Feb 1995 13:04:43 GMT
Raw View
In article <FENSTER.95Feb10184427@ground.cs.columbia.edu>,
Sam Fenster <fenster@ground.cs.columbia.edu> wrote:
>In reference to the statement that members of the unnamed namespace (which is
>meant to replace the deprecated global static) have "external linkage":
>
>>>...Does the working paper *define* "external linkage"?...
>> ...
>>  When that same "name" is used in more than one translation unit, then
>> if the name has linkage, then each name with external linkage refers to a
>> unique single entity, each of the other uses have internal linkage and refer
>> to a unique entity per translation unit.
>
>The properties of a member of the unnamed namespace seem to be those that
>you ascribe to internal linkage.

 Yes, thats right. Effectively, it works kind of like
internal linkage.  That was the original "intent", but actually
ascribing the formal property "internal linkage" to such names
leads to inconsistencies that can only be resolved with complex
rules.

 Categorically, a rational number is not a real number,
that is, the sets are distinct. That formal distinction
is really important in a strongly typed language. But mathematicians
gloss over it, because there is a monomorphism from the rationals
into the reals. However, sometimes, even in ordinary mathematics, that
glossing over leads to ambiguities. Category theory provides a
notational framework that helps eliminate such problems.

>>  Finally, if you ask "what is a name?"...it is...more like an
>> identifier and a binding to a set of declarations in the same declarative
>> region (namespace, more or less).

 This issue, by the way, is non-trivial (hard in fact),
and of semantic significance -- most such formalities are,
even if "pragmatists" refuse to accept it.

>I guess an identifier declared in the unnamed namespace of two different
>translation units is bound to two different namespaces.  And paraphrasing your
>earlier post: Even though this is functionally equivalent to internal linkage,
>it's simpler to say it's external just like members of named namespaces are;
>it's just inaccessible because its namespace has a unique, secret name.

 Yes.
>
>Is that really simpler than saying, "Things in the unnamed namespace have
>internal linkage"?

 No, of course not. It is simpler to say internal linkage,
and that is what the WP and Bjarne's original proposal said.
But that interpretation is naive. Naive is not good enough for
a Standard which is describing a formal system. Consider:

 void f(); // implies external linkage
 static void f() {} // ERROR!!

Its an error because you are not allowed to change the linkage
of a function in a subsequent declaration.  (See "Declaration
matching rules" in my ODR paper). Now consider:

 namespace X {
  void f();
  static void f(); // ERROR -- as above
 }
 namespace {
  void f();
  static void f(); // ERROR??
 }

If everything in the unnamed namespace has internal linkage,
then there is no error here. That is kind of cute:

 namespace {
  extern int x; // forward declaration of thing with internal
   // likage?
 }

or is the use of "extern" here ill formed? There are quite a few
other such examples. According to the old rules:

 class X { int x; } // linkage is indeterminate, but defaults
   // to internal
 void f(X); // now linkage of X is forced to external

and then in the unnamed namespace:

 namespace {
  class X { int x; }; // internal
  void f(X); // internal
 }

This is just too complex. The simplest rule is

 "Whether a namespace has a name or is unnamed is
 orthogonal to linkage issues"

>Is there some property of external linkage that members of
>the unnamed namespace retain?  If not, I'd say this "external, unique, secret"
>characterization is more complex and obfuscatory than the alternative.  Do you
>agree?

 No. See above.

 IMHO: The simplest rule is:

 ALL symbols have external linkage. ALL of them.

 IF the full-name of the symbol containes a UNIQUE
 part, then the name ALSO has internal linkage.

 EVERY symbol has a full-name according to the following
 rules .... (make up rules here).

[And that is the complete and total description of linkage.
Everything else then depends on the rules for how a name is
given a full name]

>By the way, thanks for the time you've taken to clarify this so far.

 Thank you also. As a (very poor) delegate of a National
Body (Standards Australia) I need information from users.
Internet is my best resource. I have better contact with US programmers
than Departments of the Australian Government :-)

>
>P.S.  Does the WP say that ::x refers to either the unnamed *or* the global
>namespace?  Does it say that those two namespaces can't contain identical
>names?

 It says -- AT PRESENT -- that ::x refers ONLY to the
global, and never to the unnamed namespace member, which is
consistent with

 namespace X { int x; }
 namespace Y { using namespace X; }
 Y::x++; // error

However, several issues regarding this have been raised and
Bjarne has suggested changing the rule so that X::x++
would work here and so that

 ::x

can refer to an x in an unnamed namespace. I do not know if this
suggestion will turn into a proposal which will be accepted.

Any comments here about it might be read by committee members
including Bjarne. I'm not certain, but the suggestion seems to
be workable in principle. Is it a good idea?

[BTW: The ANSI public review is coming up. Time to start
practicing. High quality comments are desired -- and a lot
of work is required to write them. I've been practicsing
for a while now, and I'm still not very good at it]

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Fri, 17 Feb 1995 13:13:33 GMT
Raw View
In article <FENSTER.95Feb6010203@age.cs.columbia.edu>,
Sam Fenster <fenster@age.cs.columbia.edu> wrote:
>
>schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
>> > namespace {struct A { int x; } a;};
>> >=> "A" and "a" have internal linkage.
>
>maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>>  No, actually both A and a here have _external_ linkage.
>> But the linkage names are :
>>  UNIQUE::A and UNIQUE::a
>> where UNIQUE is unique to the translation unit.
>> It's an ordinary namespace with a secret name.
>
>If it can't be accessed by any other translation unit, then in what sense does
>it have external linkage?

 It has external linkage _by presecription_. It is not
a concept. It is a rule. The rules determine the semantics.
>
>Will it be possible to define classes that are only used locally that do *not*
>clutter the global namespace?

 // file 1
 namespace { class X {}; };
 void f(X); // fine, no error, X has external linkage


 // file 2
 namespace { class X {}; };
 void f(X); // fine, no error, X has external linkage
 main() { f ( X() ); }

The program is well formed. There are two functions f(X)
with DIFFERENT signatures. Both f and both X have external
linkage. But their mangled names in both cases are
distinct. A compiler probably need not emit a public symbol
definition into the object code, because there is never
anything to link to .. HOWEVER .. given BOTH the types
X must be found using RTTI, it depends on how the
implementor creates the list of run-time type_info records.

Somehow, that list has to be linked [pun intended] together
across translation unit boundaries -- and it includes classes
with internal linkage or no linkage (i.e. local classes
still have type_info records). I'm not an implementor,
so I can't really say any more here.

[You see how tricky this stuff is?]

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Mon, 13 Feb 1995 01:08:20 GMT
Raw View
In article <3hgecg$n8o@hpsystem1.informatik.tu-muenchen.de> schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
>
>Sounds confusing ...

 The simplest solution is to get rid of internal linkage altogther.
Just define

 static int x;

to mean

 int UNIQUE_x;

and we can kiss linkage goodbye. :-)
>
>What about:
>
> namespace {
>  int f;
> };
> void  f;
>
>There is a ::f that's void and there is a UNIQUE::f that's int.
>-> ``Sorry, programmer, but with the declaration of a ::f
>     there is no way any more to access UNIQUE::f.''
>To follow the orthogonallity we must say, that this is legal.

 Yes, those are the rules at present. But don't hold your
breath, they might be changed just beacuse of this kind of issue.
>
>Whether internal or external linkage, at least unnnamed namespaces
>allow us forward-declarations contrary to static:
>
> namespace {
>  extern int a;
>  int  f () { return a; }
>  int  a = f();
> };
>[ I hope I'm correct and this is allowed ]

 I think so.
--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: fenster@ground.cs.columbia.edu (Sam Fenster)
Date: 08 Feb 1995 00:33:42 GMT
Raw View
fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:

>>>> If it can't be accessed by any other translation unit, then in what sense
>>>> does it have external linkage?
> In the sense that the working paper says so.

Boy, you smart people are hard to pin down!  "In what sense" means, "What's
the definition?"  Does the working paper *define* "external linkage"?  WHAT
DOES IT MEAN?

I ask this because my understanding of external linkage, and The C++
Programming Language 2nd Edition's description, agree that "Every declaration
of a particular name of file scope that is not declared to have internal
linkage in one of these ways in a multifile program refers to the same object,
function or class.  Such names are said to be external or to have external
linkage."  (r.3.3).

In what sense does a member of the unnamed namespace satisfy the condition
that "every declaration [of that member] in a multifile program refers to the
same object, function or class"?  Or has the definition of "external linkage"
changed?  If so, what has this change accomplished?

>> No, Max is saying that members of the unnamed namespace already have a
>> "secret" unique namespace name, but that it's somehow still "external."  My
>> question is:  How (and why) is it "external"?
>
> How: implementation-dependant.  It's up to the implementation to work out
> how.  Why: well, why not?

By "how" I meant, "By what definition."  C'monnn, be a sport, puhleeeez?  Be
helpful?

>> Is it required to be a public linker symbol?
> No, it's not.

Well, *that's* a relief!




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Thu, 9 Feb 1995 04:29:26 GMT
Raw View
In article <FENSTER.95Feb6194619@ground.cs.columbia.edu> fenster@ground.cs.columbia.edu (Sam Fenster) writes:
>In article <792085092snz@thone.demon.co.uk> andys@thone.demon.co.uk (Andy Sawyer) writes:
>
>> > > >     namespace {struct A { int x; } a;};
>> > > >=> "A" and "a" have internal linkage.
>> >
>> > maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>> > >       No, actually both A and a here have _external_ linkage.
>> > > But the linkage names are :
>> > >       UNIQUE::A and UNIQUE::a
>> > > where UNIQUE is unique to the translation unit.
>> > > It's an ordinary namespace with a secret name.
>> >
>> > If it can't be accessed by any other translation unit, then in what sense
>> > does it have external linkage?
>
>No, Max is saying that members of the unnamed namespace already have a
>"secret" unique namespace name, but that it's somehow still "external."

 Thats correct.

>My question is:  How (and why) is it "external"?

 The "why" is: there are rules about linkage which are
sort of tricky. It is by far the simplest to LEAVE THOSE RULES ALONE
and not complicate them just for the unnamed namespace.

 void f(); // defaults to external linkage
 extern void g(); // explicit external linkage
 class X { virtual void k(); } // external linkage
 void f() { ..}
 void g() { ..}

in a namespace or file scope. Now, just wrapping this in
the unnamed namespace has no effect on the linkage at all,
which is orthogonality for you. If we _dont_ do that,
what can you say about the above declarations? Without further
complicated special cases, the Working Paper would suddenly
become self-contradictory.

>Is it required to be a public linker symbol?

 Thats an implementation detail on which the Standard
cannot comment. I can though: of course no public symbol is
required, but it a compiler might emit them if you had debugging switched on.

 Not emitting the public symbols is an optimisation.
Note that ordinary "static" variables and functions can be
handled exactly the same way.

>Is there any way I can declare a class that Max would consider
>"internal"?

 No. I think that a local class has "no linkage".

 There is some confusion (in my mind at least) about
what linkage is. Linkage is an attribute of names at the top level,
specified by the programmer or deemed by the Standard, to determine
if the entities denoted in declarations in different translation
units are the same entity, or different entities.

 Any "contained" entities must "inherit" the identity
attributes of the container I'd think.  For example,
two static variables of two functions are the same variables
if, and only if, the functions are the same function.

 They do not need to have "linkage" themselves to
determine this. Thus, members do not need linkage: since
all classes at namespace scope have external linkage,
all entities declared in corresponding positions
have to be "the same" in some sense.

 What sense? Well, they have to be equivalent
functionally for all uses. Consider:

 // file 1
 int const n = 10;
 class X { void f() { static int k = n; } };

 // file 2
 int const n = 10;
 class X { void f() { static int k = n; } };

Well, the initial values of k in these two cases are the same,
but the "n" is NOT the same n. This code is legal. But, while
the code

 // file 1
 inline int n() { return 10; }
 class X { void f() { static int k = n(); } };

 // file 2
 inline int n() { return 10; }
 class X { void f() { static int k = n(); } };

is also legal, the code

 // file 1
 inline int n() { return 10; }
 class X { void f() { static int k = n(); } };

 // file 2
 const int ten = 10;
 inline int n() { return ten; }
 class X { void f() { static int k = n(); } };

is not. It breaks my formulation of the ODR.
Notice that "n()" has _internal_
linkage, so that in both these cases the definition of
a function with external linkage is _permitted_ to depend
on functions with internal linkage -- provided the
functions with internal linkage are equivalent.

Hope this helps.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Thu, 9 Feb 1995 16:53:11 GMT
Raw View
In article <FENSTER.95Feb7193342@ground.cs.columbia.edu> fenster@ground.cs.columbia.edu (Sam Fenster) writes:
>
>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>>>>> If it can't be accessed by any other translation unit, then in what sense
>>>>> does it have external linkage?
>> In the sense that the working paper says so.
>
>Boy, you smart people are hard to pin down!  "In what sense" means, "What's
>the definition?"  Does the working paper *define* "external linkage"?  WHAT
>DOES IT MEAN?
>

 Here is my understanding. Every user "name" in a C++ program
shall be ascribed one of two properties:

 1) has linkage
 2) has no linkage

and this acription is done by a set of mechanical rules given
in the Working Paper. In addition, if a name has linkage,
then it is ascribed one of two kinds of linkage:

 1) external linkage
 2) internal linkage

again by mechanical rules.

 When that same "name" is used in more than one
translation unit, then if the name has linkage, then
each name with external linkage refers to a unique single
entity, each of the other uses have internal linkage
and refer to a unique entity per translation unit.

 It is a breach of the One Definition Rule
(declaration matching subclause) if the same name
has both external and internal linkage ascribed to it
in the same translation unit.

 Finally, if you ask "what is a name?", I will
have to say that it is kind of hard to pin down: in the sense of
the Working Paper a name is not an identifier, but more
like an identifier and a binding to a set of declarations
in the same declarative region (namespace, more or less).

 For many entities, there are two important
semantic properties:

 a) equivalence
 b) identity

These include

 a) variables
 b) types
 c) functions

Equivalence means "works the same". Identity means "is the same".
For example, the function

 inline int max(int a, int b) { return a>b ? a : b; }

in two translation units "works the same" but "is not the same", because

 // file 1
 inline int max(int a, int b) { return a>b ? a : b; }
 typedef int (*binop)(int,int);
 binop max1() { return max; }

 // file 2
 inline int max(int a, int b) { return a>b ? a : b; }
 typedef int (*binop)(int,int);
 extern max1();
 binop max2() { return max; }
 main () {
  assert(max1() != max2());
 }

That is, the addresses are guarranteed to be unequal.  Whereas:

 // file 1
 extern inline int max(int a, int b) { return a>b ? a : b; }
 typedef int (*binop)(int,int);
 binop max1() { return max; }

 // file 2
 extern inline int max(int a, int b) { return a>b ? a : b; }
 typedef int (*binop)(int,int);
 extern max1();
 binop max2() { return max; }
 main () {
  assert(max1() == max2());
 }

the addresses are guarranteed to be equal.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: fenster@ground.cs.columbia.edu (Sam Fenster)
Date: 10 Feb 1995 23:44:27 GMT
Raw View
In reference to the statement that members of the unnamed namespace (which is
meant to replace the deprecated global static) have "external linkage":

maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>fenster@ground.cs.columbia.edu (Sam Fenster) writes:
>>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>>>>>> If it can't be accessed by any other translation unit, then in what
>>>>>> sense does it have external linkage?
>>> In the sense that the working paper says so.
>>...Does the working paper *define* "external linkage"?...
> ...
>  When that same "name" is used in more than one translation unit, then
> if the name has linkage, then each name with external linkage refers to a
> unique single entity, each of the other uses have internal linkage and refer
> to a unique entity per translation unit.

The properties of a member of the unnamed namespace seem to be those that
you ascribe to internal linkage.  They seem the opposite of the properties you
ascribe to external linkage.  Perhaps this explains it:

>  Finally, if you ask "what is a name?"...it is...more like an
> identifier and a binding to a set of declarations in the same declarative
> region (namespace, more or less).

I guess an identifier declared in the unnamed namespace of two different
translation units is bound to two different namespaces.  And paraphrasing your
earlier post: Even though this is functionally equivalent to internal linkage,
it's simpler to say it's external just like members of named namespaces are;
it's just inaccessible because its namespace has a unique, secret name.

Is that really simpler than saying, "Things in the unnamed namespace have
internal linkage"?  Is there some property of external linkage that members of
the unnamed namespace retain?  If not, I'd say this "external, unique, secret"
characterization is more complex and obfuscatory than the alternative.  Do you
agree?

By the way, thanks for the time you've taken to clarify this so far.

P.S.  Does the WP say that ::x refers to either the unnamed *or* the global
namespace?  Does it say that those two namespaces can't contain identical
names?




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 10 Feb 1995 19:21:52 GMT
Raw View
In article <D3ptt5.23z@ucc.su.OZ.AU>, maxtal@physics.su.OZ.AU (John Max Skaller) writes:
[..]
|>  The "why" is: there are rules about linkage which are
|> sort of tricky. It is by far the simplest to LEAVE THOSE RULES ALONE
|> and not complicate them just for the unnamed namespace.
|>
|>  void f(); // defaults to external linkage
|>  extern void g(); // explicit external linkage
|>  class X { virtual void k(); } // external linkage
|>  void f() { ..}
|>  void g() { ..}
|>
|> in a namespace or file scope. Now, just wrapping this in
|> the unnamed namespace has no effect on the linkage at all,
|> which is orthogonality for you. If we _dont_ do that,
|> what can you say about the above declarations? Without further
|> complicated special cases, the Working Paper would suddenly
|> become self-contradictory.
[..]

This is new to me, as I misinterpreted a sentence in [r.3.3.1.3]
"Unnamed namespaces make global static redundant."
as saying that members of the unnamed namespace had internal linkage
like global static objects. So this is not the case - O.K.

So by
 namespace {
  void f (); // defaults to external linkage
  class X { virtual void k(); } // external linkage
 };
 static void g ();

we get a local (in the sense of per-translation-unit) f with external linkage
and a global (in the sense of at-file-scope) g with internal linkage ?
Sounds confusing ...

What about:

 namespace {
  int f;
 };
 void  f;

There is a ::f that's void and there is a UNIQUE::f that's int.
-> ``Sorry, programmer, but with the declaration of a ::f
     there is no way any more to access UNIQUE::f.''
To follow the orthogonallity we must say, that this is legal.
I can live with that.

Whether internal or external linkage, at least unnnamed namespaces
allow us forward-declarations contrary to static:

 namespace {
  extern int a;
  int  f () { return a; }
  int  a = f();
 };
[ I hope I'm correct and this is allowed ]

Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: jason@cygnus.com (Jason Merrill)
Date: Sat, 11 Feb 1995 10:46:30 GMT
Raw View
>>>>> Sam Fenster <fenster@ground.cs.columbia.edu> writes:

> P.S.  Does the WP say that ::x refers to either the unnamed *or* the global
> namespace?  Does it say that those two namespaces can't contain identical
> names?

This issue is still in flux.

Jason




Author: fenster@age.cs.columbia.edu (Sam Fenster)
Date: 06 Feb 1995 06:02:03 GMT
Raw View
schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
> > namespace {struct A { int x; } a;};
> >=> "A" and "a" have internal linkage.

maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>  No, actually both A and a here have _external_ linkage.
> But the linkage names are :
>  UNIQUE::A and UNIQUE::a
> where UNIQUE is unique to the translation unit.
> It's an ordinary namespace with a secret name.

If it can't be accessed by any other translation unit, then in what sense does
it have external linkage?

Will it be possible to define classes that are only used locally that do *not*
clutter the global namespace?




Author: andys@thone.demon.co.uk (Andy Sawyer)
Date: Mon, 6 Feb 1995 15:38:12 +0000
Raw View
In article <FENSTER.95Feb6010203@age.cs.columbia.edu>
           fenster@age.cs.columbia.edu "Sam Fenster" writes:

> schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
> > >     namespace {struct A { int x; } a;};
> > >=> "A" and "a" have internal linkage.
>
> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
> >       No, actually both A and a here have _external_ linkage.
> > But the linkage names are :
> >       UNIQUE::A and UNIQUE::a
> > where UNIQUE is unique to the translation unit.
> > It's an ordinary namespace with a secret name.
>
> If it can't be accessed by any other translation unit, then in what sense
> does it have external linkage?
>
> Will it be possible to define classes that are only used locally that do
> *not*
> clutter the global namespace?
>

 You COULD do something like:

 namespace __FILE__ {   // Not use of preprocessor __FILE__ macro
     struct Local { int x; int y; }
 };

 Whilst I would expect the namespace to be visible at link time, its name
 should be fairly uniqe...

Regards,
 Andy
--
* Andy Sawyer ** e-mail:andys@thone.demon.co.uk ** Compu$erve:100432,1713 **
 The opinions expressed above are my own, but you are granted the right to
 use and freely distribute them. I accept no responsibility for any injury,
 harm or damage arising from their use.                --   The Management.




Author: fenster@ground.cs.columbia.edu (Sam Fenster)
Date: 07 Feb 1995 00:46:19 GMT
Raw View
In article <792085092snz@thone.demon.co.uk> andys@thone.demon.co.uk (Andy Sawyer) writes:

> > > >     namespace {struct A { int x; } a;};
> > > >=> "A" and "a" have internal linkage.
> >
> > maxtal@physics.su.OZ.AU (John Max Skaller) writes:
> > >       No, actually both A and a here have _external_ linkage.
> > > But the linkage names are :
> > >       UNIQUE::A and UNIQUE::a
> > > where UNIQUE is unique to the translation unit.
> > > It's an ordinary namespace with a secret name.
> >
> > If it can't be accessed by any other translation unit, then in what sense
> > does it have external linkage?
> >
> > Will it be possible to define classes that are only used locally that do
> > *not* clutter the global namespace?
>
>  You COULD do something like:
>
>  namespace __FILE__ {   // Note use of preprocessor __FILE__ macro
>      struct Local { int x; int y; }
>  };
>
>  Whilst I would expect the namespace to be visible at link time, its name
>  should be fairly uniqe...

No, Max is saying that members of the unnamed namespace already have a
"secret" unique namespace name, but that it's somehow still "external."  My
question is:  How (and why) is it "external"?  Is it required to be a public
linker symbol?  Is there any way I can declare a class that Max would consider
"internal"?

Besides, the __FILE__ macro would probably have punctuation in it.... :-)




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 7 Feb 1995 14:24:16 GMT
Raw View
fenster@ground.cs.columbia.edu (Sam Fenster) writes:

>andys@thone.demon.co.uk (Andy Sawyer) writes:
>
>> > > >     namespace {struct A { int x; } a;};
>> > > >=> "A" and "a" have internal linkage.
>> >
>> > maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>> > >       No, actually both A and a here have _external_ linkage.
>> > > But the linkage names are :
>> > >       UNIQUE::A and UNIQUE::a
>> > > where UNIQUE is unique to the translation unit.
>> > > It's an ordinary namespace with a secret name.
>> >
>> > If it can't be accessed by any other translation unit, then in what sense
>> > does it have external linkage?

In the sense that the working paper says so.

>> > Will it be possible to define classes that are only used locally that do
>> > *not* clutter the global namespace?

Yes, just do as above.  Even though they have external linkage,
defined in unnamed namespaces don't clutter the global namespace up at all.

>No, Max is saying that members of the unnamed namespace already have a
>"secret" unique namespace name, but that it's somehow still "external."  My
>question is:  How (and why) is it "external"?

How: implementation-dependant.  It's up to the implementation to work out how.
Why: well, why not?

>Is it required to be a public linker symbol?

No, it's not.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au
all [L] (programming_language(L), L \= "Mercury") => better("Mercury", L) ;-)




Author: jason@cygnus.com (Jason Merrill)
Date: Tue, 7 Feb 1995 12:28:22 GMT
Raw View
>>>>> Sam Fenster <fenster@ground.cs.columbia.edu> writes:

> No, Max is saying that members of the unnamed namespace already have a
> "secret" unique namespace name, but that it's somehow still "external."
> My question is: How (and why) is it "external"?  Is it required to be a
> public linker symbol?

I believe that is the general idea, though the standard says nothing about
environmental issues like that.

> Is there any way I can declare a class that Max would consider
> "internal"?

Using the unnamed namespace should be fine, since the name of the class
will be mangled such that other translation units will be unable to
reference it.

Jason




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 5 Feb 1995 20:07:26 GMT
Raw View
In article <3glnbm$b34@hpsystem1.informatik.tu-muenchen.de> schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
>
>As John Max Skaller notes, with ODR typenames have external linkage.
>[My newsserver outdated his article, so I'm relying on my memory.]

 The current rule is that a class name and all its member functions
declared in namespace scope have external linkage.  This will break
some "naughty" C programs.  However, it is a simple rule, and the old
rules wer horribly complicated. The committee got so sick of
the complicated conditions for when a class name had external linkage,
and when internal, that a proposal to make the linkage external
was welcomed with applause.

>To get internal linkage of a typename one cannot use the old "static":
>
> static struct A { int x; } a;
>
>as this defines internal linkage for the variable "a" but not for the
>struct "A"

 Yes, the name "A" has external linkage and "a"
has internal linkage.

>(?) - I'm not sure, as with the old default "internal linkage
>for types" one can't notice a difference.

 Class names, not types. "int" isn't something with linkage,
nor is "A*".

>This would be a case where the unnamed namespace is _more_ than
>(ie different to) "static":
>
> namespace {
>  struct A { int x; } a;
> };
>
>=> "A" and "a" have internal linkage.

 No, actually both A and a here have _external_ linkage.
But the linkage names are :

 UNIQUE::A and UNIQUE::a

where UNIQUE is unique to the translation unit. So the same
token in two translation units can be given, and the type "A"
and variable "a" are a distinct type and distinct variable.

 namespace { ...}

is defined (at present) to be equivalent to

 namespace UNIQUE { ... }
 using namespace UNIQUE;

It's an ordinary namespace with a secret name.
--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 31 Jan 1995 16:09:26 GMT
Raw View
As John Max Skaller notes, with ODR typenames have external linkage.
[My newsserver outdated his article, so I'm relying on my memory.]

To get internal linkage of a typename one cannot use the old "static":

 static struct A { int x; } a;

as this defines internal linkage for the variable "a" but not for the
struct "A" (?) - I'm not sure, as with the old default "internal linkage
for types" one can't notice a difference.
This would be a case where the unnamed namespace is _more_ than
(ie different to) "static":

 namespace {
  struct A { int x; } a;
 };

=> "A" and "a" have internal linkage.


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Wed, 25 Jan 1995 14:19:58 GMT
Raw View
maxtal@physics.su.OZ.AU (John Max Skaller) writes:

> // file 1
> struct A { int x; };
> struct X { int x; };
> typeinfo *t = &typeid(X);
>
> // file 2
> struct A { long x; };  // used to be OK, now violates ODR
> struct X { int x; };
> typeinfo *t1, *t2 = &typeid(X);
> void g() { assert(t1!=t2); }
>  // used to be OK, now the assertion
>  // is guarranteed to fail

I think you missed something there.  Shouldn't those last couple of lines
be

 extern typeinfo *t;
 typeinfo *t2 = &typeid(X);
 void g() { assert(t!=t2); }

rather than

> typeinfo *t1, *t2 = &typeid(X);
> void g() { assert(t1!=t2); }

?

--
Fergus Henderson - fjh@munta.cs.mu.oz.au
all [L] (programming_language(L), L \= "Mercury") => better("Mercury", L) ;-)




Author: b91926@fsgm01.fnal.gov (David Sachs)
Date: 20 Jan 1995 18:18:58 -0600
Raw View
maxtal@physics.su.OZ.AU (John Max Skaller) writes:

>In article <smeyersD2IMDE.174@netcom.com> smeyers@netcom.com (Scott Meyers) writes:
>>Is it legal to have extern inline functions?

> It is now legal to explicitly define a function:

> extern inline void f() {}

>More than one definition of such a function may be given
>(provided they are equivalent). Naturally, the addresses
>of such a function are unique. The keyword "inline"
>_must_ be given on _all_ such definitions unless there
>is exactly one.

>The principle reason this extension was blessed is that such
>functions already existed:

> struct X {
>  static void f() { } // extern and "in-class"
> };

>"inline" continues to imply "internal linkage" by default.

>--
>        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
> Maxtal Pty Ltd,
>        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
>        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189

When did the standard committee approve this?

If the address of an extern inline function is take in 2 different
compilation units, are the results guaranteed to be the same?

If an extern inline function has static variables, are they the same
in different compilation units?




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 22 Jan 1995 00:41:03 GMT
Raw View
In article <3fpjti$j5j@fsgm01.fnal.gov> b91926@fsgm01.fnal.gov (David Sachs) writes:
>maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>
>> It is now legal to explicitly define a function:
>
>> extern inline void f() {}
>
>When did the standard committee approve this?

 July 1994 I recall.
>
>If the address of an extern inline function is take in 2 different
>compilation units, are the results guaranteed to be the same?

 Yes. Its a single function, it has a unique address.
 Conversely, if there are two distinct functions they have
 distinct addresses.
>
>If an extern inline function has static variables, are they the same
>in different compilation units?

 Yes. And if there are two distinct functions, the variables
 are also distinct.

One other point you should know. ALL classes declared in a
non-local scope now have external linkage, and ALL member
functions and friends of such class _also_ must external linkage.
(It is possible to derive a class with _internal_ linkage
from a class with external linkage, but the converse should
not be permitted: a base of a class with external linkage
had better have external linkage :-)

This may break some code. Not much I hope. For example:

 // file 1
 struct A { int x; };
 struct X { int x; };
 typeinfo *t = &typeid(X);

 // file 2
 struct A { long x; };  // used to be OK, now violates ODR
 struct X { int x; };
 typeinfo *t1, *t2 = &typeid(X);
 void g() { assert(t1!=t2); }
  // used to be OK, now the assertion
  // is guarranteed to fail

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: smeyers@netcom.com (Scott Meyers)
Date: Mon, 16 Jan 1995 20:32:02 GMT
Raw View
Is it legal to have extern inline functions?  Most compilers accept
them, but one I have says that there are conflicting linkage
specifications on such functions.  I can see this, since inline means
internal linkage and extern means external linkage.  What does the
draft standard say?

Speaking of the draft standard, I've been holding off on ordering my
copy until the modifications made at the November meeting have been
included.  Has this been done?  If not, does anybody know when it will
be?  I seem to recall having been told they had to be made by the end
of the month.

Thanks,

Scott






Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Fri, 20 Jan 1995 09:54:48 GMT
Raw View
In article <smeyersD2IMDE.174@netcom.com> smeyers@netcom.com (Scott Meyers) writes:
>Is it legal to have extern inline functions?

 It is now legal to explicitly define a function:

 extern inline void f() {}

More than one definition of such a function may be given
(provided they are equivalent). Naturally, the addresses
of such a function are unique. The keyword "inline"
_must_ be given on _all_ such definitions unless there
is exactly one.

The principle reason this extension was blessed is that such
functions already existed:

 struct X {
  static void f() { } // extern and "in-class"
 };

"inline" continues to imply "internal linkage" by default.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189