Boost logo

Boost :

From: rwgk_at_[hidden]
Date: 2001-05-16 20:46:12


This posting is related to the thread
http://groups.yahoo.com/group/boost/message/11629

Attached is a bug report that I sent to Compaq, and a
response. I am very interested to hear what the authors
of the C++ standard think about the problem.
Ralf

Date: Tue, 15 May 2001 11:14:56 -0700 (PDT)
From: "Ralf W. Grosse-Kunstleve" <rwgk_at_c...>
To: compaq_cxx_at_[hidden]
Subject: cxx_bugreport: problem with friend functions in a class
template

==================== C++ Problem Reporting Template
===================

Problem description:

friend functions in a class template are instantiated correctly
but the declaration is not visible:

% cat simple.cpp
#include <iostream>

template <class T>
struct group_of_friends {
  friend T foo1(const T& v) { return v * 2; }
  friend T foo2(const T& v) {
#ifdef WORKAROUND
    T foo1(const T& v);
#endif
    return foo1(v);
  }
};

int main() {
  group_of_friends<int> f;
#ifdef WORKAROUND
  int foo2(const int& v);
#endif
  std::cout << foo2(123) << std::endl;
  return 0;
}

% cxx -std strict_ansi -o simple simple.cpp
cxx: Error: simple.cpp, line 10: identifier "foo1" is undefined
          detected during instantiation of class
                    "group_of_friends<T> [with T=int]" at line 15
    return foo1(v);
-----------^
cxx: Error: simple.cpp, line 19: identifier "foo2" is undefined
  std::cout << foo2(123) << std::endl;
---------------^
cxx: Info: 2 errors detected in the compilation of "simple.cpp".

Any additional information that we need to know:

The same code compiles fine with:
    Compaq C++ V6.2-024 for Digital UNIX V5.0 (Rev. 910)
    gcc version 2.95.2
    MIPSpro Compilers: Version 7.3.1.1m
    Visual C++ 6.0 Service Pack 4

Have you found a workaround for this problem? [X] Yes [ ] No
If 'yes', please describe the workaround.

% cxx -std strict_ansi -o simple simple.cpp -DWORKAROUND
% simple
246

------------------------- System Information -------------------------
-

cxx -V
=================================================================
Compaq C++ V6.3-008 for Compaq Tru64 UNIX V5.0A (Rev. 1094)
Compiler Driver V6.3-008 (cxx) cxx Driver
=================================================================

/usr/sbin/sizer -v
=================================================================
Compaq Tru64 UNIX V5.0A (Rev. 1094); Sat Jul 29 14:03:15 2000
=================================================================

Date: Wed, 16 May 2001 21:17:42 -0400
From: cxxc_bugs_at_[hidden]
To: rwgk_at_c...
Subject: Re: CPP#5241: Subj: cxx_bugreport: problem with friend
functions in a clas

Compaq C++ is one of the most standard conforming compilers
available. The
"-std strict_ansi" switch tells the compiler to strictly conform to
the
standard.

It is very common for code to be accepted as correct with other
compilers, but
not Compaq C++, particularly when strict conformance is requested.

This code will compile with the "-D__USE_STD_IOSTREAM" switch which
request a
standards compliant IOSTREAMS library, not is not as strict with your
code.

So is the diagnostic correct or not? The following is from the ISO
C++ standard:

===========
11.4 Friends 11 Member access control

3 A function first declared in a friend declaration has external
linkage (3.5).
its previous linkage (7.1.1).ns

5 A function can be defined in a friend declaration of a class if and
only if the
the function name is unqualified, and the
function has namespace scope.

[Example:
  class M {
    friend void f() { } // definition of global f, a friend of M,
                        // not the definition of a member function
  };
—end example] S

Such a function is implicitly inline. A friend function defined in a
class is in
(lexical) scope of the class in which it is defined. A friend function
defined outside the class is not (3.4.1).
===========

The sentense "and the function has namespace scope" makes me wonder
if the
function has to be declared first, however, that would make statement
#3
unnecessary. The following does work:

cxxosf.zko.dec.com> cxx -c -std strict_ansi t.cxx -DOK
cxxosf.zko.dec.com> cat t.cxx
typedef int T;

#ifdef OK
T foo1(const T& v);
T foo2(const T& v);
#endif

struct group_of_friends {
  friend T foo1(const T& v) { return v * 2; }
  friend T foo2(const T& v) { return foo1(v); }
};

int main() {
  group_of_friends f;
  foo2(123);

  return 0;
}

We are going to have to review this further and get back to you.

Please send all Compaq C/C++ Support requests to
cxxc_bugs_at_[hidden]
Reply to this message for further correspondence regarding THIS
support
request. Thank you for choosing Compaq C/C++.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk