Topic: Semantic inconsistency?
Author: pkt@lpi.liant.com (Scott Turner)
Date: Fri, 18 Nov 1994 17:05:04 GMT Raw View
In article <1994Nov17.115605.1298@cse.iitb.ernet.in>,
ashok@cse.iitb.ernet.in (Ashok Sreenivas) wrote:
> class A
> {
> A () {}
> friend class C;
> };
>
> class B
> {
> public :
> void f (A = A()) {}
> };
>
> class C
> {
> B b;
> public ;
> void g () { b.f (); }
> };
>
> ------------------------------------------------------------------
>
> the compilers complained that A () is a private member of class A,
> and not visible to B! Is this what is expected?
Yes.
> If it is, I think it is very strange indeed. Because a default
> parameter is just a syntactic convenience provided to all the callers.
It is intended not to work like a macro. For example, if class C were
modified to have a member 'A', as
class C
{
B b;
B A();
public ;
void g () { b.f (); }
};
that would not change the meaning of the call b.f() because its
default argument A() would still refer to the class A.
> Moreover, at all call points the compiler does know
> about the default parameters of the called function [otherwise it
> couldn't supply them!], so it should be possible to check for such
> things.
That's right. It's interesting that compilers could do this, and it
sheds a little light on the nature of the "default argument" feature.
But it is a weak reason why the language should work that way.
The same kind of question has come up more than once in the context of
typedefs. The compiler always expands typedefs at compile time, so
(in the sense you're arguing) there is not a strict need to do access
checking on typedef names. Some compilers did not. However, the
standards committee has affirmed the rule that all names have their access
checked at the point where they appear in the program. To me, this
uniformity is very attractive.
--
Scott Turner
Liant Software Corp., Framingham, Massachusetts, USA
pkt@lpi.liant.com
Author: etljck@etlxd30.ericsson.se (Jeremy Clark xr/e 4759)
Date: Mon, 21 Nov 1994 13:37:53 GMT Raw View
Ashok Sreenivas (ashok@cse.iitb.ernet.in) wrote:
> I'm not sure if the following behaviour is what is defined by the
> semantics of C++ according to the "current standard". Anyway here's
> the program first.
> ------------------------------------------------------------------
> class A
> {
> A () {}
> friend class C;
> };
> class B
> {
> public :
> void f (A = A()) {}
> };
> class C
> {
> B b;
> public ;
^^
You meant ":", right?
> void g () { b.f (); }
> };
> ------------------------------------------------------------------
> I tried this program on gcc (2.6.0) and BC (4.0 i think), and both the
> compilers complained that A () is a private member of class A, and not
> visible to B!
> Is this what is expected?
[snip!]
Yes!
So what's the problem? A() is declared private by default, so
obviously you can't construct an A for use as a default argument in B.
Declare A() public and the problem goes away :-).
--
Jeremy Clark |
West Sussex | Personal opinions only,
England | not those of my employer.
+44-444-234759 |
Author: ashok@cse.iitb.ernet.in (Ashok Sreenivas)
Date: Thu, 17 Nov 1994 11:56:05 GMT Raw View
I'm not sure if the following behaviour is what is defined by the
semantics of C++ according to the "current standard". Anyway here's
the program first.
------------------------------------------------------------------
class A
{
A () {}
friend class C;
};
class B
{
public :
void f (A = A()) {}
};
class C
{
B b;
public ;
void g () { b.f (); }
};
------------------------------------------------------------------
I tried this program on gcc (2.6.0) and BC (4.0 i think), and both the
compilers complained that A () is a private member of class A, and not
visible to B!
Is this what is expected? If it is, I think it is very strange indeed.
Because a default parameter is just a syntactic convenience provided
to all the callers. _Semantically_ it should be as if the caller (in
this case C::g) had called the function (in this case B::f) with the
parameter itself. If you do that with this program (that is remove
the default parameter from B::f, and replace b.f() with b.f(A ()), the
program compiles under both compilers!
Basically, I think default parameters should be valid at the _calling_
point and _not_ at the defining point, because they are just syntactic
work arounds. Moreover, at all call points the compiler does know
about the default parameters of the called function [otherwise it
couldn't supply them!], so it should be possible to check for such
things. Admittedly, it would make the job of the compiler writer more
painful (s/he can't just finish with processing a function at the
definition point).
I would also like to state here that this is not a "weird" program
intended to bend the compiler's or language-designer's back. We have
a "geniune" need for this in an application. Currently we're trying a
work-around by trying to "simulate" the default parameter business
through some kind of pre-processor.
Any comments welcome! Thx.
- Ashok.
P.S : I don't have easy / regular access to news, so I may not read
your responses for a week or so. However, I could be contacted by
email at ashok@trddc.ernet.in.
Ashok Sreenivas
(ashok@trddc.ernet.in / ashok@cse.iitb.ernet.in)