www.digitalmars.com         C & C++   DMDScript  

c++.windows.16-bits - 3 compile problems.

reply "Tom Udale" <tom tom.com> writes:
I have a large program that is cross compiled between win32 (using visual
studio) and win16 (msvc).  For some time I have been searching for a
replacment for msvc due since it has such a crappy c++ implementation.  I
got the Digital Mars CD some time ago and have finally managed to get enough
time to get it up to the latest patches and fix my code enough for the DM
compiler to get down to things that strike me as being compiler bugs.

Currently scver reports 8.40.2n as my compiler version which I take to be
the most recent.

At the bottom of this post are the test file and command IDE output.  The
most egregious problems are #1 and #3.  #2 is just annoying since I think I
am alright and the simple changes to fix it for DM breaks my other
compilers.

I am hardly a language lawyer so it could just be me in some cases.

I would like very much to ditch msvc so any help would be much appreciated.

Regards,

Tom Udale



// ==============================
// test.cpp

// Problem 1: Crazy derivation (it looks less crazy in context and in any
event I do not think it is illegal)
class RootA
{
public:
 virtual ~RootA();
};

class RootB
{
public:
 virtual ~RootB();
};

class Merge:public RootB,public RootA
{
public:
 ~Merge();
};

class Base:public Merge
{
};


class DBaseA:public Base
{
};

class DBaseB:public Base
{
};

class Test2:private DBaseA,private DBaseB
{
};





// Problem 2: Const and conversion operators.
// This problem was discovered with TestObj being an enum which is much more
sensible
// than the following example which I chose to show the 'fix' of adding
const to the
// return from the const conversion operator.  However, it is my
understanding
// that return values are not supposed to be part of the overload resolution
mechanism
// and if two overloaded methods differ only by constness, then the nature
of the base
// object makes the determination.  Of course, this might be somewhat
different for
// conversion operators since the return type *is* part signature (uggg).
As I think about
// it, it is not clear if the compiler should accept both the conversions on
line A and
// B (which it does)???


struct TestObj{};

class TestObjWrapper
{
    public:
 operator TestObj*();
 operator TestObj*()const;     // (A) this should work no??
 //operator const TestObj*()const;    // (B) uncomment this one for no error
at C
 TestObj*            get();     // these both work as expected.
 TestObj*            get()const;
};



void fc(const TestObj* constHandle)
{
}



void foo()
{
 TestObjWrapper   b;
 TestObjWrapper&   br=b;
 const TestObjWrapper& cbr=b;

 fc(cbr);         // (C)
 fc(cbr.get());
}


// Problem 3: Private derivation

class PrivDeriv:private RootA
{
    void    foo();
};


void foo_a(RootA&)
{
}

void PrivDeriv::foo()
{
    foo_a(*this);
}
//===============================


and here is the command line spit out by the IDE and the errors:



sc
T:\CODE\test.cpp -ml -C -WA -S -3 -a2 -Nc -c -gf -DSC_WIN16 -D_DEBUG -DSTRIC
T -DSC_APP -DSTRAIGHT_C -It:\code\xplib\50x\include -It:\code\iono_com\50x -
It:\code\iwiz\50x\ionwizrd -odebug\test.obj
Error: T:\CODE\test.cpp(35): '??_7Test2  6FRootA  Merge   ' is already
defined
Error: T:\CODE\test.cpp(79): need explicit cast for function parameter 1 to
get
T:\CODE\test.cpp(79): from: const TestObjWrapper
T:\CODE\test.cpp(79): to  : const TestObj*
Error: T:\CODE\test.cpp(98): member 'RootA' of class 'PrivDeriv' is not
accessible
Lines Processed: 97  Errors: 3  Warnings: 0
Build failed
May 11 2004
parent reply "Walter" <newshound digitalmars.com> writes:
I have to look into 1 and 2, but 3 is definitely a coding error (i.e. not a
compiler problem). I think you can fix #2 with a cast, or an #ifdef if you
must.

"Tom Udale" <tom tom.com> wrote in message
news:c7s1r4$2lb5$1 digitaldaemon.com...
 I have a large program that is cross compiled between win32 (using visual
 studio) and win16 (msvc).  For some time I have been searching for a
 replacment for msvc due since it has such a crappy c++ implementation.  I
 got the Digital Mars CD some time ago and have finally managed to get

 time to get it up to the latest patches and fix my code enough for the DM
 compiler to get down to things that strike me as being compiler bugs.

 Currently scver reports 8.40.2n as my compiler version which I take to be
 the most recent.

 At the bottom of this post are the test file and command IDE output.  The
 most egregious problems are #1 and #3.  #2 is just annoying since I think

 am alright and the simple changes to fix it for DM breaks my other
 compilers.

 I am hardly a language lawyer so it could just be me in some cases.

 I would like very much to ditch msvc so any help would be much

 Regards,

 Tom Udale



 // ==============================
 // test.cpp

 // Problem 1: Crazy derivation (it looks less crazy in context and in any
 event I do not think it is illegal)
 class RootA
 {
 public:
  virtual ~RootA();
 };

 class RootB
 {
 public:
  virtual ~RootB();
 };

 class Merge:public RootB,public RootA
 {
 public:
  ~Merge();
 };

 class Base:public Merge
 {
 };


 class DBaseA:public Base
 {
 };

 class DBaseB:public Base
 {
 };

 class Test2:private DBaseA,private DBaseB
 {
 };





 // Problem 2: Const and conversion operators.
 // This problem was discovered with TestObj being an enum which is much

 sensible
 // than the following example which I chose to show the 'fix' of adding
 const to the
 // return from the const conversion operator.  However, it is my
 understanding
 // that return values are not supposed to be part of the overload

 mechanism
 // and if two overloaded methods differ only by constness, then the nature
 of the base
 // object makes the determination.  Of course, this might be somewhat
 different for
 // conversion operators since the return type *is* part signature (uggg).
 As I think about
 // it, it is not clear if the compiler should accept both the conversions

 line A and
 // B (which it does)???


 struct TestObj{};

 class TestObjWrapper
 {
     public:
  operator TestObj*();
  operator TestObj*()const;     // (A) this should work no??
  //operator const TestObj*()const;    // (B) uncomment this one for no

 at C
  TestObj*            get();     // these both work as expected.
  TestObj*            get()const;
 };



 void fc(const TestObj* constHandle)
 {
 }



 void foo()
 {
  TestObjWrapper   b;
  TestObjWrapper&   br=b;
  const TestObjWrapper& cbr=b;

  fc(cbr);         // (C)
  fc(cbr.get());
 }


 // Problem 3: Private derivation

 class PrivDeriv:private RootA
 {
     void    foo();
 };


 void foo_a(RootA&)
 {
 }

 void PrivDeriv::foo()
 {
     foo_a(*this);
 }
 //===============================


 and here is the command line spit out by the IDE and the errors:



 sc


 It:\code\iwiz\50x\ionwizrd -odebug\test.obj
 Error: T:\CODE\test.cpp(35): '??_7Test2  6FRootA  Merge   ' is already
 defined
 Error: T:\CODE\test.cpp(79): need explicit cast for function parameter 1

 get
 T:\CODE\test.cpp(79): from: const TestObjWrapper
 T:\CODE\test.cpp(79): to  : const TestObj*
 Error: T:\CODE\test.cpp(98): member 'RootA' of class 'PrivDeriv' is not
 accessible
 Lines Processed: 97  Errors: 3  Warnings: 0
 Build failed

May 12 2004
parent reply "Tom Udale" <tom tom.com> writes:
Walter,


Thanks for looking into things.  One question.

 I have to look into 1 and 2, but 3 is definitely a coding error (i.e. not

 compiler problem). I think you can fix #2 with a cast, or an #ifdef if you
 must.

#3 is the one I was quite positive was OK. Why can't my derived class have access to its own base from within its own member function? void foo_a(RootA&) { } class PrivDeriv:private RootA { void foo(); }; void PrivDeriv::foo() { foo_a(*this); } Thanks, Tom
May 12 2004
parent reply "Walter" <newshound digitalmars.com> writes:
To have access, you need to make the derivation 'protected'. Private base
classes are not accessible. I'm not enough of an OOP expert to give a
compelling rationale for why C++ is that way, you might ask that over in
comp.std.c++.

"Tom Udale" <tom tom.com> wrote in message
news:c7u7mi$539$1 digitaldaemon.com...
 Walter,


 Thanks for looking into things.  One question.

 I have to look into 1 and 2, but 3 is definitely a coding error (i.e.


 a
 compiler problem). I think you can fix #2 with a cast, or an #ifdef if


 must.

#3 is the one I was quite positive was OK. Why can't my derived class

 access to its own base from within its own member function?

 void foo_a(RootA&)
 {
 }

 class PrivDeriv:private RootA
 {
      void    foo();
 };

 void PrivDeriv::foo()
 {
    foo_a(*this);
 }

 Thanks,

 Tom

May 13 2004
parent reply "Tom Udale" <tom tom.com> writes:
Walter,

 To have access, you need to make the derivation 'protected'. Private base
 classes are not accessible. I'm not enough of an OOP expert to give a
 compelling rationale for why C++ is that way, you might ask that over in
 comp.std.c++.

Right, but that is for further derived class, not for the _declaring_ class. The declaring class always has access to its own data, whether they be base classes or member variables. For example: class A { public: foo(); }; class B{}; void afoo(A& aref) { } void bfoo(B& aref) { } class C:private A,protected B { void foo() { A::foo(); // this has to be accessable, even though A is private, right? -C is the declaring class // (and it is in DM 8.40) A& aref=*this; // likewise, this should be accessable, but it is not. } }; void cfoo(C& aref) { } class D:private C { void foo() { A& aref=*this; // Error! I do not have access to A. DM correctly flags this. B& bref=*this; // ok, B is protected as you describe. C& cref=*this; // should be ok: C is my base but DM complains. // Try the above conversions without the intermediate reference. afoo(*this); // Error! I do not have access to C's private base bfoo(*this); // ok ,I have access to C's protected base cfoo(*this); // should be ok, I have access to my private base - DM complains. }; }; What you are talking about earlier is the access of D to private members in C. I absolutely agree that D cannot access private members (base or otherwise) of C. It does have access to C's protected base classes. However, what I am talking about is D and C's access to their _own_ base classes. Private/public/protected never affects the delcaring class. The declaring class always has access to its own members. Otherwise, they would not be able to access thier own data (which is my problem here). See also: "Re: Private inheritance" on comp.lang.c++.moderated (from May of 2000) or "Q: is this a good reason to use private inheritance" comp.lang.c++.moderated (from 1997/02/09) BTW, this behaviour changed in Digital Mars. When I originally got the CD (somwhere around 8.28), the program in question compiled fine in this partiular respect - I was only encountering problems #1 and #2. Now it has piles more errors as a result of #3. I am pretty sure it was between 38 and 40 but cannot be sure. For what its worth (and I know correctness is not a democracy :) MVSC, Visual Studio, and Watcom all compile this without complaint. Best regards, Tom
May 13 2004
parent reply "Walter" <newshound digitalmars.com> writes:
I believe DMC++'s behavior is correct according to the Standard. Of course,
I have been wrong before, but I need a compelling argument based on what the
Standard says.

"Tom Udale" <tom tom.com> wrote in message
news:c8175o$1gqa$1 digitaldaemon.com...
 BTW, this behaviour changed in Digital Mars.  When I originally got the CD
 (somwhere around 8.28), the program in question compiled fine in this
 partiular respect - I was only encountering problems #1 and #2.  Now it

 piles more errors as a result of #3.  I am pretty sure it was between 38

 40 but cannot be sure.

That's because I made a pass through the Standard to compile or issue an error message correctly for every example of correct or illegal code in the Standard with regards to access control.
 For what its worth (and I know correctness is not a democracy :) MVSC,
 Visual Studio, and Watcom all compile this without complaint.

It's common for compilers to have bugs with things like this, so what another compiler does is not sufficiently compelling. You'll need to put on your Standard Language Lawyer Hat <g>.
May 13 2004
parent reply "Tom Udale" <tom tom.com> writes:
Walter,

 I believe DMC++'s behavior is correct according to the Standard. Of

 I have been wrong before, but I need a compelling argument based on what

 Standard says.

 For what its worth (and I know correctness is not a democracy :) MVSC,
 Visual Studio, and Watcom all compile this without complaint.

It's common for compilers to have bugs with things like this, so what another compiler does is not sufficiently compelling. You'll need to put

 your Standard Language Lawyer Hat <g>.

Needless to say, even armed with the standard, my language lawyer hat fits somewhat poorly. Nevertheless, I believe the relevent section of the standard (I am looking at ISO/IEC 14882:2003) is 11.2.4: 4 A base class is said to be accessible if an invented public member of the base class is accessible. If a base class is accessible, one can implicitly convert a pointer to a derived class to a pointer to that base class (4.10, 4.11). .....In particular this next part...... [Note: it follows that members and friends of a class X can implicitly convert an X* to a pointer to a private or protected immediate base class of X. ] ...etc So by my read of the above, the following code should behave as commented: class A{}; foo(A&) { } class X:private A { void f() // Member of X { A* aptr=this; // This should work given the above note (A is an immediate base class of X). A& aref=*this; // Thus this should work since A& aref1=*aptr; // clearly this will work. foo(*this); // thefore this should work since foo(aref1); // clearly this will work } }; Does that make sense? Regards, Tom
May 14 2004
parent reply "Walter" <newshound digitalmars.com> writes:
I'll check it out. Thanks!
May 17 2004
parent "Tom Udale" <tom tom.com> writes:
 I'll check it out. Thanks!

Tom
May 18 2004