Re: C++ in kernel (was Re: exception in a device driver)

Anthony Barbachan (barbacha@Hinako.AMBusiness.com)
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/