This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Q] g++2.95.2 BUG Namespace and scoping 2
- To: gcc at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org
- Subject: [Q] g++2.95.2 BUG Namespace and scoping 2
- From: "Miljenko Jr. Jurica Cvjetko moljac" <m dot cvjetko_njet_spam at rt dot e-technik dot uni-erlangen dot de>
- Date: Tue, 09 May 2000 10:35:52 +0200
- Newsgroups: comp.lang.c++
- Organization: gcl++ Library Development
- Reply-To: m dot cvjetko_njet_spam at rt dot e-technik dot uni-erlangen dot de
/*
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
*/