This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[Q] g++2.95.2 BUG Namespace and scoping 2


/*
  Hi!

  newsgroups: 
	      comp.lang.c++
  mailing lists: 
              gcc@gcc.gnu.org
              gcc-bugs@gcc.gnu.org



  [Q] g++2.95.2 BUG Namespace and scoping

  According to Scott Meyers it is advisable to implement each
  standalone operator$ through member operator$= (More Effective C++
  Item 22), so that only assignment versions of those ops should be
  maintained, secondly to reduce friends relationships and for temporary
  object elimination (return value optimizations).

  This is what here below has been done, but with small problems for
  which I'm not sure whether those problems arise from mine misunder-
  standing of namespaces and scoping or is it g++ bug?!?!

  This is the smallest code example I could come up with. I've noticed
this
  problem in the library that I write, but it was not obvious what
  produces this error.
  
  To make ythe long story short:

  Why is Ops::operator+ **not** accessible in member function 
	       Inner2::Y<Type>::func()  ???

  Thanx a lot for Your time

  Miljenko
*/

//# define _GENERIC_OPERATORS_IN_GLOBAL_NAMESPACE_ 1 
//# define _GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_  1


# include <iostream>

//-----------------------------------------------------------------
/*
  ScottMeyers generic operator$     $ in { +,-,*,/,|,& } 
  uses operator$=
*/
# if defined _GENERIC_OPERATORS_IN_GLOBAL_NAMESPACE_

  template <class T> 
  T operator+ (const T& rhs, const T& lhs)
      {
	return T(lhs) += rhs; // tmp elimination ...
      };

# endif

# if defined _GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_

  namespace Ops
   {
     template <class T> 
       T operator+ (const T& rhs, const T& lhs)
	 {
	   return T(lhs) += rhs; // tmp elimination ...
	 };
   };
# endif

//-----------------------------------------------------------------
/* 
   some lib code...
*/
namespace Outer
{
  namespace Inner1
    {
      class X
      {
      private: 
      public:
	X& operator+=(const X& x) 
	  { 
	    std::cout << "X +=\n" ; 
	    return *this; 
	  };
      };
    };

  namespace Inner2
    {
      template <class Type >
      class Y
      {
      private: 
      public:
	Y<Type >& operator+=(const Y<Type >& x) 
	  { 
	    std::cout << "Y<Type > +=\n" ; 

	    return *this; 
	  };

	void func(void) 
	  { 
	    # if defined _GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_
	      using namespace Ops;

	      /*
		Can I explicitly declare usage of operator+ and how??
		something like:
		using Ops::operator+;
	      */

	    # endif

	    Y<Type > a; 
	    Y<Type > b; 
	    Y<Type > c = a + b; 

	    
	    return ; 
	  };
      };

    };
};


int test()
{
  Outer::Inner1::X x1;

  using Outer::Inner1::X;
  X x2;

  using namespace Outer::Inner2;

  # if defined _GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_
  using namespace Ops;
  # endif

  X x3 = x1 + x2;

  using Outer::Inner2::Y;

  Y<X > yx1_;
  Y<X > yx2_;
  Y<X > yx3_ = yx1_+ yx2_;
	yx3_.func();


  Y<char > yc1_;
  Y<char > yc2_;
  Y<char > yc3_ = yc1_+ yc2_;
	   yc3_.func();
  
  return 0;
};

int main()
{
  using Outer::Inner1::X;

  X x1;
  X x2;

  # if defined _GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_
  using namespace Ops;
  # endif

  X x3 = x1 + x2;

  return test();
}

/*
  To avoid collisions with other generic operators +, -, *, / ..., 
  for example from other libraries or even mine for some other purposes, 
  mine operators have been encapsulated in separate namespace. On the
other
  hand classes implement Class::operator$= which will be used by
operator$.
  The problem is when the operator$ is used no appropriate operator call
is
  found. 
  Why is it so? Is it a my error or what??

  compilation results for operators in local namespace scope:

gcl@robby:~/gcl/src/example/Test/syntax_standard_comformance/namespace >
g++ -v -D _GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_
generic_operator_in_another_scope_problems_2_TO_ASK.cpp 
Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/specs
gcc version 2.95.2 19991024 (release)
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cpp -lang-c++ -v -D__GNUC__=2
-D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -D__ELF__ -Dunix
-D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix
-D__linux -Asystem(posix) -D__EXCEPTIONS -Acpu(i386) -Amachine(i386)
-Di386 -D__i386 -D__i386__ -Di686 -Dpentiumpro -D__i686 -D__i686__
-D__pentiumpro -D__pentiumpro__ -D
_GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_
generic_operator_in_another_scope_problems_2_TO_ASK.cpp /tmp/ccw0RC7h.ii
GNU CPP version 2.95.2 19991024 (release) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../include/g++-3
 /usr/local/include

/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../i686-pc-linux-gnu/include
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/include
 /usr/include
End of search list.
The following default directories have been omitted from the search
path:
End of omitted list.
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cc1plus /tmp/ccw0RC7h.ii
-quiet -dumpbase generic_operator_in_another_scope_problems_2_TO_ASK.cc
-version -o /tmp/ccOYsd2Y.s
GNU C++ version 2.95.2 19991024 (release) (i686-pc-linux-gnu) compiled
by GNU C version 2.95.2 19991024 (release).
generic_operator_in_another_scope_problems_2_TO_ASK.cpp: In method `void
Outer::Inner2::Y<Outer::Inner1::X>::func()':
generic_operator_in_another_scope_problems_2_TO_ASK.cpp:147:  
instantiated from here
generic_operator_in_another_scope_problems_2_TO_ASK.cpp:116: no match
for `Outer::Inner2::Y<Outer::Inner1::X> & +
Outer::Inner2::Y<Outer::Inner1::X> &'
generic_operator_in_another_scope_problems_2_TO_ASK.cpp: In method `void
Outer::Inner2::Y<char>::func()':
generic_operator_in_another_scope_problems_2_TO_ASK.cpp:153:  
instantiated from here
generic_operator_in_another_scope_problems_2_TO_ASK.cpp:116: no match
for `Outer::Inner2::Y<char> & + Outer::Inner2::Y<char> &'

  

  But if the generic operator$ is in global namespace, there's no
problems,

  compilation results for operators in global namespace scope:

gcl@robby:~/gcl/src/example/Test/syntax_standard_comformance/namespace >
g++ -v -D _GENERIC_OPERATORS_IN_GLOBAL_NAMESPACE_
generic_operator_in_another_scope_problems_2_TO_ASK.cpp 
Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/specs
gcc version 2.95.2 19991024 (release)
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cpp -lang-c++ -v -D__GNUC__=2
-D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -D__ELF__ -Dunix
-D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix
-D__linux -Asystem(posix) -D__EXCEPTIONS -Acpu(i386) -Amachine(i386)
-Di386 -D__i386 -D__i386__ -Di686 -Dpentiumpro -D__i686 -D__i686__
-D__pentiumpro -D__pentiumpro__ -D
_GENERIC_OPERATORS_IN_GLOBAL_NAMESPACE_
generic_operator_in_another_scope_problems_2_TO_ASK.cpp /tmp/ccjDynS3.ii
GNU CPP version 2.95.2 19991024 (release) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../include/g++-3
 /usr/local/include

/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../i686-pc-linux-gnu/include
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/include
 /usr/include
End of search list.
The following default directories have been omitted from the search
path:
End of omitted list.
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cc1plus /tmp/ccjDynS3.ii
-quiet -dumpbase generic_operator_in_another_scope_problems_2_TO_ASK.cc
-version -o /tmp/cc2uUV67.s
GNU C++ version 2.95.2 19991024 (release) (i686-pc-linux-gnu) compiled
by GNU C version 2.95.2 19991024 (release).
 as -V -Qy -o /tmp/ccCwRTSs.o /tmp/cc2uUV67.s
GNU assembler version 2.9.1 (i486-linux), using BFD version 2.9.1.0.22
 /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/collect2 -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/crtbegin.o
-L/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2 -L/usr/i686-pc-linux-gnu/lib
/tmp/ccCwRTSs.o -lstdc++ -lm -lgcc -lc -lgcc
/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/crtend.o /usr/lib/crtn.o

 programm run:

X +=
X +=
Y<Type > +=
Y<Type > +=
Y<Type > +=
Y<Type > +=


  Well here's Borlands bcc55 result:

>bcc32 -v -D_GENERIC_OPERATORS_IN_GLOBAL_NAMESPACE_ -Id:\bcc55\include -Ld:\bcc55\lib g.cpp 
Borland C++ 5.5 for Win32 Copyright (c) 1993, 2000 Borland
g.cpp:
Warning W8037 g.cpp 50: Non-const function Outer::Inner1::X::operator
+=(const Outer::Inner1::X &) called for const object in function
operator + <Outer::Inner1::X>(const Outer::Inner1::X &,const Oute
Warning W8037 g.cpp 50: Non-const function
Outer::Inner2::Y<Outer::Inner1::X>::operator +=(const
Outer::Inner2::Y<Outer::Inner1::X> &) called for const object in
function operator + <Outer::Inner2::Y<
Warning W8037 g.cpp 50: Non-const function
Outer::Inner2::Y<char>::operator +=(const Outer::Inner2::Y<char> &)
called for const object in function operator + <Outer::Inner2::Y<char>
>(const Outer::Inn
Warning W8057 g.cpp 99: Parameter 'x' is never used in function
Y<Inner1::X>::operator +=(const Y<Inner1::X> &)
Warning W8057 g.cpp 99: Parameter 'x' is never used in function
Y<char>::operator +=(const Y<char> &)
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland


>bcc32 -v -D_GENERIC_OPERATORS_IN_LOCAL_NAMESPACE_ -Id:\bcc55\include -Ld:\bcc55\lib g.cpp 
Borland C++ 5.5 for Win32 Copyright (c) 1993, 2000 Borland
g.cpp:
Warning W8037 g.cpp 62: Non-const function Outer::Inner1::X::operator
+=(const Outer::Inner1::X &) called for const object in function
operator + <Outer::Inner1::X>(const Outer::Inner1::X &,const Oute
Warning W8037 g.cpp 62: Non-const function
Outer::Inner2::Y<Outer::Inner1::X>::operator +=(const
Outer::Inner2::Y<Outer::Inner1::X> &) called for const object in
function operator + <Outer::Inner2::Y<
Warning W8037 g.cpp 62: Non-const function
Outer::Inner2::Y<char>::operator +=(const Outer::Inner2::Y<char> &)
called for const object in function operator + <Outer::Inner2::Y<char>
>(const Outer::Inn
Warning W8057 g.cpp 99: Parameter 'x' is never used in function
Y<Inner1::X>::operator +=(const Y<Inner1::X> &)
Warning W8057 g.cpp 99: Parameter 'x' is never used in function
Y<char>::operator +=(const Y<char> &)


 ** NOTE **
 Borland compiler compiles it w/o any errors, except those suspicious
warrnings
 W8037 for non const function which is wrong according to my opinion.

 Thanks a lot

 mc
 */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]