c++.windows.16-bits - 3 compile problems.
- Tom Udale (115/115) May 11 2004 I have a large program that is cross compiled between win32 (using visua...
- Walter (15/128) May 12 2004 I have to look into 1 and 2, but 3 is definitely a coding error (i.e. no...
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 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
I have to look into 1 and 2, but 3 is definitely a coding error (i.e. not a 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 getenoughtime 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. TheIam 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 muchappreciated.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 muchmoresensible // 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 overloadresolutionmechanism // 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 conversionsonline 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 noerrorat 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: scT:\CODE\test.cpp -ml -C -WA -S -3 -a2 -Nc -c -gf -DSC_WIN16 -D_DEBUG -DSTRICT -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 1toget 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
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. notamust.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
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.notI have to look into 1 and 2, but 3 is definitely a coding error (i.e.ayouhavemust.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
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 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
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 thishasand40 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
Walter,I believe DMC++'s behavior is correct according to the Standard. Ofcourse,I have been wrong before, but I need a compelling argument based on whattheStandard says.Of course.onFor 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 putyour Standard Language Lawyer Hat <g>.Ok, you have forced me to finally buy the standard :) 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
I'll check it out. Thanks!Ok, great. Thanks alot. Tom
May 18 2004