Topic: Question on scope resolution
Author: "Gabor Greif" <gabor@no.netopia.com>
Date: 1999/03/16 Raw View
We have here a problem with one of our compiler vendors neglecting an issue
we believe is a compiler bug.
I the following snippet
#####################################
#include <iostream>
class A
{
static const char* foo() { return "A"; }
};
class B : public A
{
static const char* foo() { return "B"; }
};
int main(void)
{
std::cout << "should read \"A\" in the next line..." << std::endl
<< B::A::foo() << std::endl; // <<<<<<< error here
}
#####################################
the aforementioned compiler produces the error "A is not a member of B".
So far we have dug up the following excerpts from the (dec 96 WP version)
of the C++ standard:
FROM: 3.4.5 Class member access [basic.lookup.classref]
[Note: because the name of a class is inserted in its class scope (9), the
name of a
class is also considered a nested member of that class. ]
FROM: 10 Derived classes [class.derived]
in paragraph 1:
Inherited members can be referred to in expressions in the same manner as
other
members of the derived class, unless their names are hidden or ambiguous
(10.2).
[Note: the scope resolution operator :: (5.1) can be used to refer to a
direct or
indirect base member explicitly. This allows access to a name that has
been
redefined in the derived class.
ALSO section 10.2 Member name lookup [class.member.lookup]
We believe by combining these lines it should be clear that B::A::foo() is
a legal expression in the above context because of:
1) A is a baseclass of B, so by 3.4.5 it is considered a nested member of
B
2) by 10/1 the scope resolution B::A can be used to get to the scope of A
3) by 10.2, foo can be accessed by the scope resolution B::A::foo
4) so calling the static member function foo of A should be possible by
B::A::foo()
Can the language lawyers comment on this with a few words?
Thanks in advance,
Gabor Greif, Netopia Development GmbH
PS: I have been so explicit in this case (where much less would have been
sufficient normally) because we need some hard evidence for hindering the
vendor from breaking out of responsibility acknowledging this particular
case being a bug. The above argumentation has been rejected by the vendor
with the words
"... However, I cannot find anything in the spec that says B::A::foo() is
allowed
or not. So, the behaviour is undefined in this case - different compilers
may
implement it differently"
Not being able to prove the contrary results in financial consequenses for
us.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/03/16 Raw View
On 16 Mar 99 11:39:05 GMT, Gabor Greif <gabor@no.netopia.com> wrote:
> << B::A::foo() << std::endl; // <<<<<<< error here
(Replace 'struct' with 'class'.) Egcs compiles and runs this.
(Use 'iostream.h' and no 'std::'.) Como compiles and runs this.
The code appears to be well-formed, and it certainly makes sense.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/03/16 Raw View
Gabor Greif wrote:
>
> We have here a problem with one of our compiler vendors neglecting an issue
> we believe is a compiler bug.
>
> I the following snippet
>
> #####################################
> #include <iostream>
>
> class A
> {
> static const char* foo() { return "A"; }
> };
>
> class B : public A
> {
> static const char* foo() { return "B"; }
> };
>
> int main(void)
> {
> std::cout << "should read \"A\" in the next line..." << std::endl
> << B::A::foo() << std::endl; // <<<<<<< error here
> }
> #####################################
By default, the members of a class are private, so foo is inaccesible
from main(). Make them explicitly public, or use structs, where the
default is public.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@dejanews.com (formerly AllanW@my-dejanews.com <allan_w@my-dejanews.com>)
Date: 1999/03/18 Raw View
In article <B313F707-7F797@192.168.1.8>,
"Gabor Greif" <gabor@no.netopia.com> wrote:
> We have here a problem with one of our compiler vendors neglecting an issue
> we believe is a compiler bug.
>
> I the following snippet
>
> #####################################
> #include <iostream>
>
> class A
> {
public: // I assume you meant the function to be public
> static const char* foo() { return "A"; }
> };
>
> class B : public A
> {
public: // I assume you meant the function to be public
> static const char* foo() { return "B"; }
> };
>
> int main(void)
> {
> std::cout << "should read \"A\" in the next line..." << std::endl
> << B::A::foo() << std::endl; // <<<<<<< error here
> }
> #####################################
>
> the aforementioned compiler produces the error "A is not a member of B".
This certainly ought to work, for reasons you expressed quite well.
I tried it on my compiler (Microsoft Visual C++ 5.0) and got these
messages:
error C2039: 'A' : is not a member of 'B'
error C2065: 'foo' : undeclared identifier
I changed the program to call A::foo() and B::foo(). Both of these
worked correctly; it's only B::A::foo() that fails.
I removed the "static" keywords and rewrote main():
int main() {
A a;
B b;
std::cout << a.foo() << std::endl; // Worked
std::cout << b.foo() << std::endl; // Worked
std::cout << a.A::foo() << std::endl; // Worked
std::cout << b.B::foo() << std::endl; // Worked
std::cout << b.A::foo() << std::endl; // Worked
// error C2039: 'A' : is not a member of 'B'
std::cout << b.B::A::foo() << std::endl;
return 0;
}
If your compiler is Microsoft VC++, I have found a work-around you
might be able to use:
// Instead of defining A, use a different name and then use typedef:
class xxA { public:
static const char*foo() { return "A"; }
};
typedef xxA A;
// Inside B, repeat the typedef
class B : public A {
static const char*foo() { return "B"; }
typedef xxA A; // or typedef ::xxA A; // repeat the typedef
};
// Now the original main() will work
int main(void) {
std::cout << "should read \"A\" in the next line..." << std::endl
<< B::A::foo() << std::endl;
}
----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@dejanews.com (formerly AllanW@my-dejanews.com <allan_w@my-dejanews.com>)
Date: 1999/03/18 Raw View
In article <B313F707-7F797@192.168.1.8>,
"Gabor Greif" <gabor@no.netopia.com> wrote:
> We have here a problem with one of our compiler vendors neglecting an issue
> we believe is a compiler bug.
>
> I the following snippet
>
> #####################################
> #include <iostream>
>
> class A
> {
public: // I assume you meant the function to be public
> static const char* foo() { return "A"; }
> };
>
> class B : public A
> {
public: // I assume you meant the function to be public
> static const char* foo() { return "B"; }
> };
>
> int main(void)
> {
> std::cout << "should read \"A\" in the next line..." << std::endl
> << B::A::foo() << std::endl; // <<<<<<< error here
> }
> #####################################
>
> the aforementioned compiler produces the error "A is not a member of B".
This certainly ought to work, for reasons you expressed quite well.
I tried it on my compiler (Microsoft Visual C++ 5.0) and got these
messages:
error C2039: 'A' : is not a member of 'B'
error C2065: 'foo' : undeclared identifier
I changed the program to call A::foo() and B::foo(). Both of these
worked correctly; it's only B::A::foo() that fails.
I removed the "static" keywords and rewrote main():
int main() {
A a;
B b;
std::cout << a.foo() << std::endl; // Worked
std::cout << b.foo() << std::endl; // Worked
std::cout << a.A::foo() << std::endl; // Worked
std::cout << b.B::foo() << std::endl; // Worked
std::cout << b.A::foo() << std::endl; // Worked
// error C2039: 'A' : is not a member of 'B'
std::cout << b.B::A::foo() << std::endl;
return 0;
}
If your compiler is Microsoft VC++, I have found a work-around you
might be able to use:
// Instead of defining A, use a different name and then use typedef:
class xxA { public:
static const char*foo() { return "A"; }
};
typedef xxA A;
// Inside B, repeat the typedef
class B : public A {
static const char*foo() { return "B"; }
typedef xxA A; // or typedef ::xxA A; // repeat the typedef
};
// Now the original main() will work
int main(void) {
std::cout << "should read \"A\" in the next line..." << std::endl
<< B::A::foo() << std::endl;
}
----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]