Messages in this thread | | | From | "Anthony Barbachan" <> | Subject | Re: C++ in kernel (was Re: exception in a device driver) | Date | Sat, 16 Jan 1999 22:17:35 -0500 |
| |
-----Original Message----- From: Khimenko Victor <khim@sch57.msk.ru> To: chip@perlsupport.com <chip@perlsupport.com>; khim@sch57.msk.ru <khim@sch57.msk.ru> Cc: scherrey@proteus-tech.com <scherrey@proteus-tech.com>; scherrey@gte.net <scherrey@gte.net>; alan@lxorguk.ukuu.org.uk <alan@lxorguk.ukuu.org.uk>; linux-kernel@vger.rutgers.edu <linux-kernel@vger.rutgers.edu>; kwrohrer@enteract.com <kwrohrer@enteract.com>; ncm@cantrip.org <ncm@cantrip.org> Date: Saturday, January 16, 1999 3:33 PM Subject: Re: C++ in kernel (was Re: exception in a device driver)
>In <19990116134342.E4232@perlsupport.com> Chip Salzenberg (chip@perlsupport.com) wrote: >CS> According to Khimenko Victor: >>> In <19990115230842.C767@perlsupport.com> Chip Salzenberg (chip@perlsupport.com) wrote: >>> CS> According to Khimenko Victor: >>> >> Even two constructs like >>> >> A. someclass var(1); >>> >> B. someclass var=1; >>> >> are NOT equal! >>> >>> CS> Yes, and ... ? Initialization and assignment are entirely different >>> CS> animals in C++. Anyone who doesn't know that isn't ready to _read_ >>> CS> C++ code, much less write it. >>> >>> Uh, oh, bummmm. This mean that YOU are one who "isn't ready to _read_ C++ code, >>> much less write it". (Hint: there are NO assignment in BOTH constructs!). > >CS> You are mistaken, again. Statement (B) is default construction of >CS> var, followed by construction of a temporary "someclass(1)", followed >CS> by assignment of that temporary to var, followed by destruction of the >CS> temporary. The compiler may elide the contruction and destruction of >CS> the temporary under many circumstances; but the semantics are clear >CS> nonetheless. > >Great ! And you still think that this language is usefull for anything ? >When even expirienced programmer (I think that you are expirienced C++ >programmer :-) could do stupid mistakes in trivial cases like that ? > >-- cut -- >class test { > int x; >public: > test(int i) : x(i) {} > test(const test& t) : x(t.x) {} >private: > test& operator=(const test& t) { x=t.x; return *this; } >}; > >void main() { > test A=1; > A=2; >} >-- cut -- > >Try to compile this program. "test A=1;" will be accepted while "A=2;" will be >rejected. And if you think that all you compilers are broken then think about >-- cut -- > int i; > int &r=i; >-- cut -- >and eat shit :-)) (I'm does not have latest ANSI C++ standard handy but if >now "int &r=i;" is not assignment while "someclass var=1;" is assignment then >C++ is now even more cryptic then it used to be)... >
Again something that could be easily handled by limiting "creative" uses of C++. Just using a regular constructor and calling it in a normal way (ex. classptr = new classname(param, ...);) works perfectly well, is perfectly readable, straitforward, and understandable. Using this example to criticize C++ is much less fair than Java trying to use pointers to criticize C/C++. At lease pointers are used and must be used commonly in C/C++. The above is need not be implemented in the way it was, I could write just as crappy code in C if I decided to be creative.
>>> >> If you'll use objects you are tied to VERY LIMITED C++ object model. >>> >>> CS> That's a feature, not a bug. C++'s object model is limited to >>> CS> features that have efficient implementation and which penalize only >>> CS> those who use them. >>> >>> Yes, but why use it at all ? > >CS> Static type checking with knowledge of inheritance; forced >CS> construction and destruction; convenience. (C already has adequate >CS> static type checking if you use composition instead of inheritance.) > >Forced destruction with temporary variables is biggest nightmare of C++ >(something like (string("a")+string("b")).c_str and such) while forced >contruction is not so big win. What about convenience... Just discussed
No need to use temporary variables, again an example of people generally trying to be creative. A class could easily be implemented to assign strings in a more effient manner, somthing like stringname.assign_string("a", "b");.
>example is enough to prove otherwise IMO. Language so cryptic that even >expirienced programmer could do mistakes even in simpliest contructions >could not inprove convenience. No way. >
C can even be more cryptic, especially with the extensive use of macros.
>>> CS> Base *target = new Derived1; >>> CS> // begin transmogrification >>> CS> void *p = dynamic_cast<void *>(target); >>> CS> target->~Base(); >>> CS> target = new (p) Derived2; >>> CS> // end transmogrification >>> >>> CS> Tadaa, all done. Only requirement is that the new class be no larger >>> CS> than the old one -- same as C. :-) >>> >>> Unfortunatelly this is >>> 1. Not feature of C++ but feature of GNU C++ (i.e.: non-portable; still most >>> implementation will work Ok here). > >CS> You are mistaken, again. This is 100% ANSI C++. I wrote it with the >CS> ANSI standard open in another window. > >TEXT is 100% ANSI C++. Workability -- implementation specific... >sizeof(Derived2) <= sizeof(Derived1) is NOT enough. UNLIKE C ! Since even if >sizeof(Derived2) <= sizeof(Derived1) it's NOT guaranteed that >void * operator new (size_t size, void *p placement) throw() >will be called with size_t < sizeof(Derived1) !!! Think about implementation >where each object not on stack or in array is prefixed with information for >profiler, for example. So this could be considered as non-portable low-level >hack at most :-)) GREAT for portable program like perl !!! > >>> 2. Since target could change value after such "change nature of your class" >>> so it's not exactly change nature of your class -- more like optimization >>> of new/delete call. > >CS> It is _exactly_ changing the nature of an object (not a class, but I >CS> think that's just a typo on your part). Consider that we may choose >CS> to define a constructor for Derived2 that omits the initialization of >CS> member variables, thus inheriting previous values from Derived1. > >Of course it was type. I mean changing nature of object, not class (hm, hm, >changing nature of class is possible in C as well :-). This is NOT change of >object nature. As result we could get different object with different address... >When I refer to "change nature of your object" I refer to ability to get new >object in the same place of memory with different behaviour (most OOP-languages >does not have this ability but it's easily doable with artifactual >objects/classes in C). Now take a look: >
This can be done in C++. You could do the same function pointer hack within a C++ class. You could keep that particular rare implementation in C as well. You could also do this with virtually inherited children.
>-- cut -- >#include <iostream> >#include <memory> > >struct Base { > int x; > Base(int _x) : x(_x) { } > virtual foo() { std::cout << "Base::foo, x= " << x << endl; } > virtual ~Base() { } >}; > >struct OtherClass { > int z; > OtherClass(int _z) : z(_z) { } > virtual bar() { std::cout << "OtherClass::bar, z= " << z << endl; } > virtual ~OtherClass() { } >}; > >struct Derived1 : OtherClass, Base { > int t; > Derived1(int _x, int _z, int _t) : Base(_x), OtherClass(_z), t(_t) { } > virtual bar() { > std::cout << "Derived1::bar, x = " << x << ", z = " << z > << ", t= " << t << endl; } > virtual foo() { > std::cout << "Derived1::foo, x = " << x << ", z = " << z > << ", t= " << t << endl; } > virtual ~Derived1() { } >}; > >struct Derived2 : Base { > int y; > Derived2(int _x, int _y) : Base(_x), y(_y) { } > virtual foo() { std::cout << "Derived2::foo, x = " << x << ", y= " << y << endl; } > virtual ~Derived2() { } >}; > >main() { > Base *target = new Derived1(1,2,3); > Base *copyptr = target; > // Cast to Derived2 > void *p = dynamic_cast<void *>(target); > target->~Base(); > target = new (p) Derived2(4,5); > target->foo(); > copyptr->foo(); > delete target; >} >-- cut -- > >Result (with egcs 1.1b on Linux): >-- cut -- >Derived2::foo, x = 4, y= 5 >Base::foo, x= 5 >-- cut -- >Not good :-( Implementation is allowed to do such shift even with single >inheritance. Most will not do of course. Other reason why this non-portable >low-level hack is not usefull for portable programs :-))
Umm, the C function pointer sceme is also a hack, in that case to implement an object-like model.
> > > > >- >To unsubscribe from this list: send the line "unsubscribe linux-kernel" in >the body of a message to majordomo@vger.rutgers.edu >Please read the FAQ at http://www.tux.org/lkml/ >
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |