Topic: Redundant Using Declarations


Author: schuenem@informatik.tu-muenchen.de (Ulf Schuenemann)
Date: 1995/05/31
Raw View
In article <3pvffk$jo5@offas_dike.sbil.co.uk>, shepherd@debussy.sbi.com (Marc Shepherd) writes:
[..]
|> I think we can agree that the following is well-formed:
|>
|>    namespace A2 {
|>       using A::i;
|>       using A::i;     // ok: double declaration
|>       extern int j;
|>       extern int j;   // ok: double declaration
|>    }

I'm afraid by the current wording of the standard it's not what you intend:
7.3.1.4 Namespace member definitions [namespace.memdef] 4 says:
> When an entity declared with the extern specifier is not found to refer
> to some other declarartion, then that entity is a member of the innermost
> enclosing namespace.

I can't see anything there that prevents me from concluding that you
are declaring ::j and not A2::j.
I find this situation very very unpleasent.

   HOW CAN I _DECLARE_ A NAMESPACE-MEMBERVARIABLE ???

It would be a shame, if namespaces where mainly designed for functions
(that need no extern) but not also for objects.

7.3.1.4 gives an example with extern within the body of a namespace-
memberfunction. The analogon for a namespace-membernamespace:

namespace X {
 namespace p {
  extern int q; // a is a member of namespace X ???
  int f ()
  { return q; } // referes to X::q ???
 }
 int middle ()
 { return p::q; }  // error: q not yet declared ???

 int p::q = 2;  // error: q is not a member of p ???
}

IMHO the wording should be changed at least to something like:
> Within a scope that is not a namespace, when an entity declared with
> the extern specifier ...

NOTE: As I understand 7.3.1.4 this is not a clarification but a change !


Ulf Schuenemann

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






Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/05/28
Raw View
In article <3pvffk$jo5@offas_dike.sbil.co.uk>,
Marc Shepherd <shepherd@debussy.sbi.com> wrote:
>In article Ew2@ucc.su.OZ.AU, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>>In article <3pi75q$ihm@offas_dike.sbil.co.uk>,
>>Marc Shepherd <shepherd@debussy.sbi.com> wrote:
>::Subclause 7.3.3 of the draft WP says:
>::
>::   A using-declaration is a declaration and can therefore be
>::   used repeatedly where (and only where) multiple declarations
>::   are allowed.
>>
>> No: a definition is also a declaration, and it _cannot_
>>be repeated: it isn't a question of where "multiple declarations"
>>are allowed: multiple definitions in the one scope are never
>>allowed, and multiple declarations which are not definitions
>>always are. (Multiple declarations which are not definitions
>>must obey certain rules about not changing linkage attributes
>>or type or return type)
>
>I'm not sure what you're saying "no" to.  The passage above was
>quoted directly from the WP.  Are you saying the WP is incorrect?

 It certainly is not making a coherent normative statement.
Such imprecise gobbledegook is not suitable for a Standard.

 As I said, every definition is a declaration. There is
no question of ANY context in which "multiple declarations are
allowed". It may be that multiple declarations of some name are always
allowed in some contexts and that of these declarations at most
one may also be a definition.

>I think we can agree that the following is well-formed:
>
>   namespace A2 {
>      using A::i;
>      using A::i;     // ok: double declaration
>      extern int j;
>      extern int j;   // ok: double declaration
>   }

 Right.

>Consider the following:
>
>   void f()
>   {
>      using A::i;
>      using A::i;     // error, according to the example from the WP quoted above
>      extern int j;
>      extern int j;   // my Sun 4.0 compiler accepts this,
>                      // and I find no text in the WP that disallows it
>   }

 Yep -- the WP is wrong in my opinion.
>
>The two using declarations and the two extern declarations above are all
>plain declarations, not definitions.  Yet, the redundant externs seem to
>be well-formed, but the example in the WP says that the two using's are
>not.

 Yes, its wrong.
>
>So, pardon my persistence, but it *still* seems to me that either the
>normative text or the example--one or the other--is wrong.

 I agree. The example is wrong, and the text you quote
is not precise enough to be considered in any way "normative text".

 The rule is simple: if you can write a using declaration,
you can write any number of them including repetitions.

 That is, "using X::f;" means "ensure that a use of
plain 'f' finds X::f". I use the word "ensure" to suggest
there is no error ensuring something more than once.

 The reason this behaviour is essential -- there is no
other alternative -- is as follows:

 namespace A { int i; }
 namespace B { using A::i; }
 namespace C { using A::i; }

 using namespace A;
 using namespace B;

We do not want an error here -- there is only one "i" in namespace A.
The using directive treat this code "as if"

 namespace A { int i; }
 using A::i;
 using A::i;

had been written -- so it had better not be an error.

BTW: I think the WP is getting confused about

 void f() {
  int i;
  int i;
 }

in which case the two declarations _are_ definitions.

--
        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: shepherd@debussy.sbi.com (Marc Shepherd)
Date: 1995/05/24
Raw View
In article Ew2@ucc.su.OZ.AU, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>In article <3pi75q$ihm@offas_dike.sbil.co.uk>,
>Marc Shepherd <shepherd@debussy.sbi.com> wrote:
::Subclause 7.3.3 of the draft WP says:
::
::   A using-declaration is a declaration and can therefore be
::   used repeatedly where (and only where) multiple declarations
::   are allowed.
>
> No: a definition is also a declaration, and it _cannot_
>be repeated: it isn't a question of where "multiple declarations"
>are allowed: multiple definitions in the one scope are never
>allowed, and multiple declarations which are not definitions
>always are. (Multiple declarations which are not definitions
>must obey certain rules about not changing linkage attributes
>or type or return type)

I'm not sure what you're saying "no" to.  The passage above was
quoted directly from the WP.  Are you saying the WP is incorrect?

::
::It further gives the following examples of this rule:
::
::   namespace A {
::      int i;
::   }
::
::   namespace A1 {
::      using A::i;
::      using A::i; // ok: double declaration
::   }
::
::   void f()
::   {
::      using A::i;
::      using A::i; // error: double declaration
::   }
::
::   class B {
::      int i;
::   };
::
::   class X : public B {
::      using B::i;
::      using B::i; // error: double member declaration
::   };
::
::My question is: in the definition of namespace A1 shown above, why
::is the redundant using declaration of A::i well-formed, considering
::that the following would not be:
::
::   namespace A1 {
::      int i;
::      int i;
::   }
>
> Because the declaration "int i" is a definition.

I take your point.  I gave a bad example.  Let me give a better one.
I think we can agree that the following is well-formed:

   namespace A2 {
      using A::i;
      using A::i;     // ok: double declaration
      extern int j;
      extern int j;   // ok: double declaration
   }

Consider the following:

   void f()
   {
      using A::i;
      using A::i;     // error, according to the example from the WP quoted above
      extern int j;
      extern int j;   // my Sun 4.0 compiler accepts this,
                      // and I find no text in the WP that disallows it
   }

The two using declarations and the two extern declarations above are all
plain declarations, not definitions.  Yet, the redundant externs seem to
be well-formed, but the example in the WP says that the two using's are
not.

So, pardon my persistence, but it *still* seems to me that either the
normative text or the example--one or the other--is wrong.

---
Marc Shepherd
Salomon Brothers Inc
shepherd@schubert.sbi.com The opinions I express are no one's but mine!






Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/05/21
Raw View
In article <3pi75q$ihm@offas_dike.sbil.co.uk>,
Marc Shepherd <shepherd@debussy.sbi.com> wrote:
>Subclause 7.3.3 of the draft WP says:
>
>   A using-declaration is a declaration and can therefore be
>   used repeatedly where (and only where) multiple declarations
>   are allowed.

 No: a definition is also a declaration, and it _cannot_
be repeated: it isn't a question of where "multiple declarations"
are allowed: multiple definitions in the one scope are never
allowed, and multiple declarations which are not definitions
always are. (Multiple declarations which are not definitions
must obey certain rules about not changing linkage attributes
or type or return type)
>
>It further gives the following examples of this rule:
>
>   namespace A {
>      int i;
>   }
>
>   namespace A1 {
>      using A::i;
>      using A::i; // ok: double declaration
>   }
>
>   void f()
>   {
>      using A::i;
>      using A::i; // error: double declaration
>   }
>
>   class B {
>      int i;
>   };
>
>   class X : public B {
>      using B::i;
>      using B::i; // error: double member declaration
>   };
>
>My question is: in the definition of namespace A1 shown above, why
>is the redundant using declaration of A::i well-formed, considering
>that the following would not be:
>
>   namespace A1 {
>      int i;
>      int i;
>   }

 Because the declaration "int i" is a definition.

--
        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: shepherd@debussy.sbi.com (Marc Shepherd)
Date: 1995/05/19
Raw View
Subclause 7.3.3 of the draft WP says:

   A using-declaration is a declaration and can therefore be
   used repeatedly where (and only where) multiple declarations
   are allowed.

It further gives the following examples of this rule:

   namespace A {
      int i;
   }

   namespace A1 {
      using A::i;
      using A::i; // ok: double declaration
   }

   void f()
   {
      using A::i;
      using A::i; // error: double declaration
   }

   class B {
      int i;
   };

   class X : public B {
      using B::i;
      using B::i; // error: double member declaration
   };

My question is: in the definition of namespace A1 shown above, why
is the redundant using declaration of A::i well-formed, considering
that the following would not be:

   namespace A1 {
      int i;
      int i;
   }



---
Marc Shepherd
Salomon Brothers Inc
shepherd@schubert.sbi.com The opinions I express are no one's but mine!