public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ language lawyer question
@ 2004-03-10  4:47 Albert Chin
  2004-03-10  8:05 ` Gabriel Dos Reis
  2004-03-15  9:54 ` Nathan Sidwell
  0 siblings, 2 replies; 19+ messages in thread
From: Albert Chin @ 2004-03-10  4:47 UTC (permalink / raw)
  To: gcc

In the process of compiling KDE 3.2 on IRIX 6.5 and Tru64 UNIX 5.1
with the respective vendor C++ compilers, I ran into a namespace
issue. Consider the following:

$ cat a.h
class KMAcctImap;

namespace KIO {
  class Job {
  public:
    int b;
  };
}

namespace KMail {
  class ImapJob {
    friend class KMAcctImap;
  public:
    ImapJob();

  private:
    KIO::Job *mJob;
  };
}

$ cat b.cpp
namespace KIO {
  class Job;
}
namespace KMail {
  class ImapJob;
}
using KMail::ImapJob;

class KMAcctImap
{
  friend class KMail::ImapJob;

public:
  void test (void);
};

#include "a.h"

void KMAcctImap::test (void) {
  ImapJob *f = new ImapJob ();

  if (f->mJob)
    int b;
}


Compile results with different compilers:
  (Solaris Sun One 8 compiler)
    $ CC -c b.cpp
    "b.cpp", line 22: Error: mJob is not accessible from KMAcctImap::test().
    1 Error(s) detected.
  (HP-UX C++ compiler)
    $ aCC -c b.cpp
    Error 182: "b.cpp", line 22 # "void KMAcctImap::test()" cannot access
    private
        member "KIO::Job *KMail::ImapJob::mJob".
          if (f->mJob)
              ^^^^^^^ 
  (IRIX C++ compiler)
    $ CC -c b.cpp
    cc-1238 CC: ERROR File = b.cpp, Line = 22
      The member "KMail::ImapJob::mJob" is inaccessible.

        if (f->mJob)
               ^
  (IBM C++ compiler)
    $ xlC -c b.cpp
    [success]
  (Tru64 UNIX C++ compiler)
    $ cxx -c b.cpp
    cxx: Error: b.cpp, line 22: member "KMail::ImapJob::mJob" is inaccessible
      if (f->mJob)
    ---------^
  (GCC 3.3.2 with some patches from 3.3.3 merged in)
    $ g++ -c b.cpp
    [success]

I can cause a successful compile by changing:
  namespace KMail {
    class ImapJob {
      friend class KMAcctImap;
to:
  namespace KMail {
    class ImapJob {
      friend class ::KMAcctImap;
                   ^^

So, who is right and why?

-- 
albert chin (china@thewrittenword.com)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2004-03-10  4:47 C++ language lawyer question Albert Chin
@ 2004-03-10  8:05 ` Gabriel Dos Reis
  2004-03-15  9:54 ` Nathan Sidwell
  1 sibling, 0 replies; 19+ messages in thread
From: Gabriel Dos Reis @ 2004-03-10  8:05 UTC (permalink / raw)
  To: gcc

Albert Chin <gcc@lists.thewrittenword.com> writes:

| In the process of compiling KDE 3.2 on IRIX 6.5 and Tru64 UNIX 5.1
| with the respective vendor C++ compilers, I ran into a namespace
| issue. Consider the following:

This is really a question for comp.lang.c++.moderated or comp.std.c++.

| $ cat a.h
| class KMAcctImap;
| 
| namespace KIO {
|   class Job {
|   public:
|     int b;
|   };
| }
| 
| namespace KMail {
|   class ImapJob {
|     friend class KMAcctImap;

In a friend declaration like that, if the thingy being given a
friendship is unqualified, then either there is a matching declaration
in the enclosing scope or it is considered invisibly declared in the 
innermost enclosing namespace.  So KMAcctImap is invisibly declared in
KMail::.  So despite appearance, you're not saying that ::KMAcctImap is 
friend of KMail::ImapJob.  If a compiler does not understand that,
then it has a bug in that area (that is the only point that makes your
posting relevant here because GCC does not get it right :-().

[...]

| I can cause a successful compile by changing:
|   namespace KMail {
|     class ImapJob {
|       friend class KMAcctImap;
| to:
|   namespace KMail {
|     class ImapJob {
|       friend class ::KMAcctImap;
|                    ^^
| 
| So, who is right and why?

See above.

-- Gaby

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2004-03-10  4:47 C++ language lawyer question Albert Chin
  2004-03-10  8:05 ` Gabriel Dos Reis
@ 2004-03-15  9:54 ` Nathan Sidwell
  2004-03-15 10:19   ` Gabriel Dos Reis
  1 sibling, 1 reply; 19+ messages in thread
From: Nathan Sidwell @ 2004-03-15  9:54 UTC (permalink / raw)
  To: gcc

Albert Chin wrote:
> In the process of compiling KDE 3.2 on IRIX 6.5 and Tru64 UNIX 5.1
> with the respective vendor C++ compilers, I ran into a namespace
> issue. Consider the following:
> 
> $ cat a.h
> class KMAcctImap;
> 
> namespace KIO {
>   class Job {
>   public:
>     int b;
>   };
> }
> 
> namespace KMail {
>   class ImapJob {
>     friend class KMAcctImap;
AFAICT [11.4]/9 indicates that this already means ::KMAcctImap,
You look for the name as normal, and then if not found inject
it into the innermost non-class scope (but in such a way that
regular name lookup won't find it until there's matching
declaration)

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2004-03-15  9:54 ` Nathan Sidwell
@ 2004-03-15 10:19   ` Gabriel Dos Reis
  0 siblings, 0 replies; 19+ messages in thread
From: Gabriel Dos Reis @ 2004-03-15 10:19 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: gcc

Nathan Sidwell <nathan@codesourcery.com> writes:

| Albert Chin wrote:
| > In the process of compiling KDE 3.2 on IRIX 6.5 and Tru64 UNIX 5.1
| > with the respective vendor C++ compilers, I ran into a namespace
| > issue. Consider the following:
| > $ cat a.h
| > class KMAcctImap;
| > namespace KIO {
| >   class Job {
| >   public:
| >     int b;
| >   };
| > }
| > namespace KMail {
| >   class ImapJob {
| >     friend class KMAcctImap;
| AFAICT [11.4]/9 indicates that this already means ::KMAcctImap,

I disagree.  11.4/9 says:

  If a friend declaration appears in a local class (9.8) and the name
  specified is an unqualified name, a prior declaration is looked up
  without considering scopes that are outside the innermost enclosing
  non-class scope. For a friend function declaration, if there is no
  prior declaration, the program is ill-formed. For a friend class
  declaration, if there is no prior declaration, the class that is
  specified belongs to the innermost enclosing non-class scope, but if
  it is subsequently referenced, its name is not found by name lookup
  until a matching declaration is provided in the innermost enclosing
  nonclass scope. 

Here, the friend declaration *does not appear in local class*.
And even if it were local class, the innermost nonclass scope is that
of the namespace KMail, not the global scope.

The relevant chapter and verse for the particular case under
discussion is explicitly covered by 7.3.1.2/3:

  Every name first declared in a namespace is a member of that
  namespace. If a friend declaration in a non-local class first
  declares a class or function83) the friend class or function is a
  member of the innermost enclosing namespace. The name of the friend
  is not found by simple name lookup until a matching declaration
  is provided in that namespace scope (either before or after the
  class declaration granting friendship). If a friend function is
  called, its name may be found by the name lookup that considers
  functions from namespaces and classes associated with the types of
  the function arguments (3.4.2). When looking for a prior declaration
  of a class or a function declared as a friend, and when the name of
  the friend class or function is neither a qualified name nor a
  template-id, scopes outside the innermost enclosing namespace
  scope are not considered.

Again, the innermost namespace to consider is KMail, not the global
namespace. Hence, GCC behaviour is wrong.

-- Gaby

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ Language Lawyer Question
  2004-02-10 20:09 ` Gabriel Dos Reis
@ 2004-02-10 20:39   ` Joel Sherrill
  0 siblings, 0 replies; 19+ messages in thread
From: Joel Sherrill @ 2004-02-10 20:39 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: 'gcc@gcc.gnu.org'

Gabriel Dos Reis wrote:

> Joel Sherrill <joel.sherrill@OARcorp.com> writes:
> 
> | Hi,
> | 
> | I was surprised that a particular piece of code compiled
> | (with gcc 2.96 and 3.2.3 on RedHat 7.3) and wanted a
> | language lawyer to tell me if this code should have.
> | The issue is that I accidentally made a type definition
> | private when it was used as an argument to a public method.
> | 
> | namespace N {
> |    class C {
> |      private:
> |        typedef int T1_t;
> |      protected:
> |        typedef int T2_t;
> |      public:
> |        C();
> |        ~C();
> |        int f1(T1_t);  // private type used for public method
> |        int f2(T2_t);  // protected type used for public method
> |    };
> | }
> | 
> | N::C::C() { ; }
> | N::C::~C() { ; }
> | int N::C::f1(T1_t x) { return x+1; }
> | int N::C::f2(T2_t x) { return x+2; }
> | 
> | Should this work?
> 
> Yes, the program is well-formed.  Access control is applied to names,
> and the check is done in their contexts of use.  You may even be able
> to call N::C::f1() with an argument of type int with no error.
> 
> | If so, what is the rationale for allowing it.
> 
> I'm afraid I don't understand what you mean here.
> The general philosophy is that you can use a name everywhere it is
> visible and accessible.  N::C::T1_t is usable and accessible in the
> scope of  N::C::f.

I think you guys have definitely give me reason to believe that there
are good reasons for it being legal even if it is a bit non-intuitive
at first glance.  Using the output of a function returning a private
type like T1_t and using that as input makes sense.

Thanks.

--joel

> -- Gaby


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ Language Lawyer Question
  2004-02-10 19:43 ` Giovanni Bajo
@ 2004-02-10 20:11   ` Gabriel Dos Reis
  0 siblings, 0 replies; 19+ messages in thread
From: Gabriel Dos Reis @ 2004-02-10 20:11 UTC (permalink / raw)
  To: Giovanni Bajo; +Cc: Joel Sherrill, gcc

"Giovanni Bajo" <giovannibajo@libero.it> writes:

| Joel Sherrill wrote:
| 
| > namespace N {
| >    class C {
| >      private:
| >        typedef int T1_t;
| >      protected:
| >        typedef int T2_t;
| >      public:
| >        C();
| >        ~C();
| >        int f1(T1_t);  // private type used for public method
| >        int f2(T2_t);  // protected type used for public method
| >    };
| > }
| >
| > N::C::C() { ; }
| > N::C::~C() { ; }
| > int N::C::f1(T1_t x) { return x+1; }
| > int N::C::f2(T2_t x) { return x+2; }
| >
| > Should this work?  If so, what is the rationale for allowing it.
| 
| Yes, there is nothing wrong with it. The fact that you can't directly name a
| C::T1_t doesn't make the member function useless. For instance, you could have
| a public member function in C which returns a T1_t (so that you can call it
| directly while calling f1()). Or you could call f1() with any other type for
| which there is a default conversion to T1_t.

Yes, you're even able to say

    C().f1(90);

-- Gaby

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ Language Lawyer Question
  2004-02-10 19:34 C++ Language Lawyer Question Joel Sherrill
  2004-02-10 19:40 ` Eric Christopher
  2004-02-10 19:43 ` Giovanni Bajo
@ 2004-02-10 20:09 ` Gabriel Dos Reis
  2004-02-10 20:39   ` Joel Sherrill
  2 siblings, 1 reply; 19+ messages in thread
From: Gabriel Dos Reis @ 2004-02-10 20:09 UTC (permalink / raw)
  To: Joel Sherrill; +Cc: 'gcc@gcc.gnu.org'

Joel Sherrill <joel.sherrill@OARcorp.com> writes:

| Hi,
| 
| I was surprised that a particular piece of code compiled
| (with gcc 2.96 and 3.2.3 on RedHat 7.3) and wanted a
| language lawyer to tell me if this code should have.
| The issue is that I accidentally made a type definition
| private when it was used as an argument to a public method.
| 
| namespace N {
|    class C {
|      private:
|        typedef int T1_t;
|      protected:
|        typedef int T2_t;
|      public:
|        C();
|        ~C();
|        int f1(T1_t);  // private type used for public method
|        int f2(T2_t);  // protected type used for public method
|    };
| }
| 
| N::C::C() { ; }
| N::C::~C() { ; }
| int N::C::f1(T1_t x) { return x+1; }
| int N::C::f2(T2_t x) { return x+2; }
| 
| Should this work?

Yes, the program is well-formed.  Access control is applied to names,
and the check is done in their contexts of use.  You may even be able
to call N::C::f1() with an argument of type int with no error.

| If so, what is the rationale for allowing it.

I'm afraid I don't understand what you mean here.
The general philosophy is that you can use a name everywhere it is
visible and accessible.  N::C::T1_t is usable and accessible in the
scope of  N::C::f.

-- Gaby

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ Language Lawyer Question
  2004-02-10 19:34 C++ Language Lawyer Question Joel Sherrill
  2004-02-10 19:40 ` Eric Christopher
@ 2004-02-10 19:43 ` Giovanni Bajo
  2004-02-10 20:11   ` Gabriel Dos Reis
  2004-02-10 20:09 ` Gabriel Dos Reis
  2 siblings, 1 reply; 19+ messages in thread
From: Giovanni Bajo @ 2004-02-10 19:43 UTC (permalink / raw)
  To: Joel Sherrill, gcc

Joel Sherrill wrote:

> namespace N {
>    class C {
>      private:
>        typedef int T1_t;
>      protected:
>        typedef int T2_t;
>      public:
>        C();
>        ~C();
>        int f1(T1_t);  // private type used for public method
>        int f2(T2_t);  // protected type used for public method
>    };
> }
>
> N::C::C() { ; }
> N::C::~C() { ; }
> int N::C::f1(T1_t x) { return x+1; }
> int N::C::f2(T2_t x) { return x+2; }
>
> Should this work?  If so, what is the rationale for allowing it.

Yes, there is nothing wrong with it. The fact that you can't directly name a
C::T1_t doesn't make the member function useless. For instance, you could have
a public member function in C which returns a T1_t (so that you can call it
directly while calling f1()). Or you could call f1() with any other type for
which there is a default conversion to T1_t.

There are worse things in the C++ standard which are allowed and totally
useless, like a template constructor whose template arguments can't be deduced,
or a partial specialization where the argument are used only in non-deduced
contexts.

Giovanni Bajo


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ Language Lawyer Question
  2004-02-10 19:34 C++ Language Lawyer Question Joel Sherrill
@ 2004-02-10 19:40 ` Eric Christopher
  2004-02-10 19:43 ` Giovanni Bajo
  2004-02-10 20:09 ` Gabriel Dos Reis
  2 siblings, 0 replies; 19+ messages in thread
From: Eric Christopher @ 2004-02-10 19:40 UTC (permalink / raw)
  To: Joel Sherrill; +Cc: 'gcc@gcc.gnu.org'


> I was surprised that a particular piece of code compiled
> (with gcc 2.96 and 3.2.3 on RedHat 7.3) and wanted a

Still compiles on mainline too. Haven't looked up the language.

-eric

-- 
Eric Christopher <echristo@redhat.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* C++ Language Lawyer Question
@ 2004-02-10 19:34 Joel Sherrill
  2004-02-10 19:40 ` Eric Christopher
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Joel Sherrill @ 2004-02-10 19:34 UTC (permalink / raw)
  To: 'gcc@gcc.gnu.org'


Hi,

I was surprised that a particular piece of code compiled
(with gcc 2.96 and 3.2.3 on RedHat 7.3) and wanted a
language lawyer to tell me if this code should have.
The issue is that I accidentally made a type definition
private when it was used as an argument to a public method.

namespace N {
   class C {
     private:
       typedef int T1_t;
     protected:
       typedef int T2_t;
     public:
       C();
       ~C();
       int f1(T1_t);  // private type used for public method
       int f2(T2_t);  // protected type used for public method
   };
}

N::C::C() { ; }
N::C::~C() { ; }
int N::C::f1(T1_t x) { return x+1; }
int N::C::f2(T2_t x) { return x+2; }

Should this work?  If so, what is the rationale for allowing it.
If not, is this a known issue with G++?

Thanks.

--joel sherrill


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-30  9:52     ` Gabriel Dos Reis
@ 2003-10-02 21:02       ` Gerald Pfeifer
  0 siblings, 0 replies; 19+ messages in thread
From: Gerald Pfeifer @ 2003-10-02 21:02 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: gcc, gcc-patches, Mike Stump

[ Reply-To: gcc-patches ]

On Tue, 30 Sep 2003, Gabriel Dos Reis wrote:
> Despite what has been claimed about the simplicy of the issue, it is
> not as clear cut some would like to believe.

Thanks, at least my intuition wasn't completely off-base. ;-)

> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#209
>
> I believe your addition to changes.html should include that link.

Definitely, thanks for the pointer.

On Tue, 30 Sep 2003, Gabriel Dos Reis wrote:
> "need to be public" is both too strong and incomplete.
> What is required is that every name used in the friend declaration be
> accessible at the point of declaration.

I was aware of the fact that my wording was a bit sloopy, but you are
right, it was in fact too sloppy (and, worse, I even committed the bad
version as part of a different patch today, unintentionally of course.)

What do you think about the rewrite below? (Not installed yet.)

Gerald

Index: changes.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.4/changes.html,v
retrieving revision 1.51
diff -u -3 -p -r1.51 changes.html
--- changes.html	2 Oct 2003 10:14:48 -0000	1.51
+++ changes.html	2 Oct 2003 20:58:38 -0000
@@ -177,10 +177,13 @@
 	template &lt;typename T&gt;
 	void f(T);</pre></li>

-    <li>In case of friend declarations that refer to members of a class,
-        these members need to be <code>public</code>, whereas G++ used to
-        accept <code>private</code>/<code>protected</code> members as well.
-        </li>
+    <li>In case of friend declarations, every name used in the friend
+        declaration must be accessible at the point of that declaration.
+        Previous versions of G++ used to be less strict about this and
+        allowed friend declarations for <code>private</code> class members,
+        for example.  See the ISO C++ Standard Committee's <a
+        href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#209">defect
+        report #209.</a> for details.</li>

     <li>You must use <code>template &lt;&gt;</code> to introduce template
 	specializations, as required by the standard.  For example,

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-30  0:42   ` Gerald Pfeifer
  2003-09-30  1:17     ` Bruce Stephens
@ 2003-09-30  9:52     ` Gabriel Dos Reis
  2003-10-02 21:02       ` Gerald Pfeifer
  1 sibling, 1 reply; 19+ messages in thread
From: Gabriel Dos Reis @ 2003-09-30  9:52 UTC (permalink / raw)
  To: Gerald Pfeifer; +Cc: Mike Stump, gcc

Gerald Pfeifer <gerald@pfeifer.com> writes:

| +    <li>In case of friend declarations that refer to members of a class,
| +        these members need to be <code>public</code>, whereas G++ used to
| +        accept <code>private</code>/<code>protected</code> members as well.

"need to be public" is both too strong and incomplete.
What is required is that every name used in the friend declaration be
accessible at the point of declaration.

-- Gaby

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-29 23:21 C++ language lawyer question Gerald Pfeifer
  2003-09-29 23:29 ` Bruce Stephens
  2003-09-29 23:46 ` Mike Stump
@ 2003-09-30  9:18 ` Gabriel Dos Reis
  2 siblings, 0 replies; 19+ messages in thread
From: Gabriel Dos Reis @ 2003-09-30  9:18 UTC (permalink / raw)
  To: Gerald Pfeifer; +Cc: gcc

Gerald Pfeifer <gerald@pfeifer.com> writes:

| Current mainline issues the following error
| 
|   x.cc:2: error: `void A::a()' is private
|   x.cc:6: error: within this context
| 
| for this snippet:
| 
|   class A {
|      void a();
|   };
| 
|   class B {
|      friend void A::a();
|   };
| 
| I'm not a language lawyer, but is this really correct? (Intuitively, it
| seems quite backwards.)

Gerald --

  Despite what has been claimed about the simplicy of the issue, it is
not as clear cut some would like to believe.  Exactly the issue you're
raising has been a subject of a DR, and although it has been decided
to resolve it as a NAD, it is highly instructive to read

  http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#209


What is amusing is the rationale for resolving the issue as a NAD:

  Ultimately it was decided that the original perceived defect was not
  sufficiently serious as to warrant the degree of complexity required
  to resolve it satisfactorily and the issue was consequently declared
  not to be a defect. It was observed that most of the problems
  involved with the current state of affairs result from inability to
  declare a particular member function as a friend; in such cases, an
  easy workaround is simply to befriend the entire class rather than
  the specific member function.   

I believe your addition to changes.html should include that link.

-- Gaby

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-30  1:17     ` Bruce Stephens
@ 2003-09-30  2:15       ` Mike Stump
  0 siblings, 0 replies; 19+ messages in thread
From: Mike Stump @ 2003-09-30  2:15 UTC (permalink / raw)
  To: Bruce Stephens; +Cc: gcc

On Monday, September 29, 2003, at 04:29 PM, Bruce Stephens wrote:
> Gerald Pfeifer <gerald@pfeifer.com> writes:
>
> [...]
>
>> ...and if the "invited" friend is a member of a class, it must not
>> be private or protected.  This is the difference between GCC 3.3 and
>> 3.4.
>
> Ah, I see.  Interesting question: can one bestow friendship on a
> private or protected member.  Yes, that requires a language lawyer.
> I've got the standard, but I'm not sure I'd be able to work out the
> answer from it.

The standard is extremely simplistic wrt access control...  I don't see 
anything hard about it.  :-)

You can't access things, unless you have been declared a friend, or, 
the stuff is public.  What can't you access, everything, types, 
members...  The code in question violates that simple clause, and the 
answer to how to make it work, is contained in that one clause.

The hard part, is realizing that g++ has historically been too lax and 
permitted things it should not have.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-30  0:42   ` Gerald Pfeifer
@ 2003-09-30  1:17     ` Bruce Stephens
  2003-09-30  2:15       ` Mike Stump
  2003-09-30  9:52     ` Gabriel Dos Reis
  1 sibling, 1 reply; 19+ messages in thread
From: Bruce Stephens @ 2003-09-30  1:17 UTC (permalink / raw)
  To: gcc

Gerald Pfeifer <gerald@pfeifer.com> writes:

[...]

> ...and if the "invited" friend is a member of a class, it must not
> be private or protected.  This is the difference between GCC 3.3 and
> 3.4.

Ah, I see.  Interesting question: can one bestow friendship on a
private or protected member.  Yes, that requires a language lawyer.
I've got the standard, but I'm not sure I'd be able to work out the
answer from it.

[...]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-29 23:46 ` Mike Stump
@ 2003-09-30  0:42   ` Gerald Pfeifer
  2003-09-30  1:17     ` Bruce Stephens
  2003-09-30  9:52     ` Gabriel Dos Reis
  0 siblings, 2 replies; 19+ messages in thread
From: Gerald Pfeifer @ 2003-09-30  0:42 UTC (permalink / raw)
  To: Mike Stump; +Cc: gcc

On Mon, 29 Sep 2003, Mike Stump wrote:
> Naw, this is an intro to C++ question.

Well, GCC up to and including GCC 3.3 gets it wrong ;-) -- that's why
I wondered when encountering this problem in a third-party application
(TaskJuggler).

> Yes, it is correct.  A friend can't claim friendship, the person
> bestowing friendship must make the claim.

...and if the "invited" friend is a member of a class, it must not be
private or protected.  This is the difference between GCC 3.3 and 3.4.

How about the doc patch below? (It may be a bit too oversimplified...)

Gerald

Index: changes.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.4/changes.html,v
retrieving revision 1.49
diff -u -3 -p -r1.49 changes.html
--- changes.html	29 Sep 2003 17:53:08 -0000	1.49
+++ changes.html	29 Sep 2003 23:17:49 -0000
@@ -176,7 +176,12 @@
 	<pre>
 	template &lt;typename T&gt;
 	void f(T);</pre></li>
-
+
+    <li>In case of friend declarations that refer to members of a class,
+        these members need to be <code>public</code>, whereas G++ used to
+        accept <code>private</code>/<code>protected</code> members as well.
+        </li>
+
     <li>You must use <code>template &lt;&gt;</code> to introduce template
 	specializations, as required by the standard.  For example,
 	<pre>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-29 23:21 C++ language lawyer question Gerald Pfeifer
  2003-09-29 23:29 ` Bruce Stephens
@ 2003-09-29 23:46 ` Mike Stump
  2003-09-30  0:42   ` Gerald Pfeifer
  2003-09-30  9:18 ` Gabriel Dos Reis
  2 siblings, 1 reply; 19+ messages in thread
From: Mike Stump @ 2003-09-29 23:46 UTC (permalink / raw)
  To: Gerald Pfeifer; +Cc: gcc

On Monday, September 29, 2003, at 03:41 PM, Gerald Pfeifer wrote:
> Current mainline issues the following error
>
>   x.cc:2: error: `void A::a()' is private
>   x.cc:6: error: within this context
>
> for this snippet:
>
>   class A {
>      void a();
>   };
>
>   class B {
>      friend void A::a();
>   };
>
> I'm not a language lawyer, but is this really correct? (Intuitively, it
> seems quite backwards.)

Naw, this is an intro to C++ question.  Yes, it is correct.  A friend 
can't claim friendship, the person bestowing friendship must make the 
claim.

class A {
	friend B;
	void a();
};

would allow A::a to work in B.  It is that, or make a public.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: C++ language lawyer question
  2003-09-29 23:21 C++ language lawyer question Gerald Pfeifer
@ 2003-09-29 23:29 ` Bruce Stephens
  2003-09-29 23:46 ` Mike Stump
  2003-09-30  9:18 ` Gabriel Dos Reis
  2 siblings, 0 replies; 19+ messages in thread
From: Bruce Stephens @ 2003-09-29 23:29 UTC (permalink / raw)
  To: gcc

Gerald Pfeifer <gerald@pfeifer.com> writes:

> Current mainline issues the following error
>
>   x.cc:2: error: `void A::a()' is private
>   x.cc:6: error: within this context
>
> for this snippet:
>
>   class A {
>      void a();
>   };
>
>   class B {
>      friend void A::a();
>   };
>
> I'm not a language lawyer, but is this really correct? (Intuitively, it
> seems quite backwards.)

It seems correct to me, and makes sense.  (I'm not a language lawyer,
however.)

class A can say that class B (or some method in class B) is a friend.
But class B can't claim to be a friend of some private method of class
A.  So I think the example you give above has it backwards: class B
can't poke its way uninvited into class A.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* C++ language lawyer question
@ 2003-09-29 23:21 Gerald Pfeifer
  2003-09-29 23:29 ` Bruce Stephens
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Gerald Pfeifer @ 2003-09-29 23:21 UTC (permalink / raw)
  To: gcc

Current mainline issues the following error

  x.cc:2: error: `void A::a()' is private
  x.cc:6: error: within this context

for this snippet:

  class A {
     void a();
  };

  class B {
     friend void A::a();
  };

I'm not a language lawyer, but is this really correct? (Intuitively, it
seems quite backwards.)

Gerald
-- 
Gerald Pfeifer (Jerry)   gerald@pfeifer.com   http://www.pfeifer.com/gerald/

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2004-03-15 10:19 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-10  4:47 C++ language lawyer question Albert Chin
2004-03-10  8:05 ` Gabriel Dos Reis
2004-03-15  9:54 ` Nathan Sidwell
2004-03-15 10:19   ` Gabriel Dos Reis
  -- strict thread matches above, loose matches on Subject: below --
2004-02-10 19:34 C++ Language Lawyer Question Joel Sherrill
2004-02-10 19:40 ` Eric Christopher
2004-02-10 19:43 ` Giovanni Bajo
2004-02-10 20:11   ` Gabriel Dos Reis
2004-02-10 20:09 ` Gabriel Dos Reis
2004-02-10 20:39   ` Joel Sherrill
2003-09-29 23:21 C++ language lawyer question Gerald Pfeifer
2003-09-29 23:29 ` Bruce Stephens
2003-09-29 23:46 ` Mike Stump
2003-09-30  0:42   ` Gerald Pfeifer
2003-09-30  1:17     ` Bruce Stephens
2003-09-30  2:15       ` Mike Stump
2003-09-30  9:52     ` Gabriel Dos Reis
2003-10-02 21:02       ` Gerald Pfeifer
2003-09-30  9:18 ` Gabriel Dos Reis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).