LWN.net Logo

Quote of the week

Quote of the week

Posted Dec 9, 2004 8:25 UTC (Thu) by simlo (subscriber, #10866)
In reply to: Quote of the week by elanthis
Parent article: Quote of the week

In honesty, it doesn't matter - most of the truly interesting C++ stuff (i.e., the stuff beyond just syntactic sugar) really isn't a good idea to use in a kernel, and I'd rather the developers use what they're comfortable with.

I don't know what you call interesting in C++, but I can easily point out 2 places where C++ would be really nice:

1) Instead of using pointers to a struct of function pointers use virtual functions in C++. What will actually happen runtime will be the same.

2) Ingo Molnar have replaces spin-locks with muteces in his real-time patch. Some are left as spin-locks, some are changed. But the interface is the same. So how does the kernel know which function to call when the lock has to be locked/unlocked? This is now done by explicitly making typecheck's with if's in the code. Ugly! In C++ you just overload the function. It will all be done compile time! In general it is much easier to fix interfaces in C++ without breaking compability with existing code - without making extra runtime checks!

C++ also has a lot stronger type-checking so you can do a lot more checking compile time.

I don't know about templates. In some way they are very elegant and I have done some really nice stuff with them. You can make the compiler do a hell of a lot of the work for you and make much more efficient code because a lot of the logic can be done compile-time. But they are really hell to debug from outsiders and doesn't really work the same in all compilers...


(Log in to post comments)

Quote of the week

Posted Dec 9, 2004 18:01 UTC (Thu) by iabervon (subscriber, #722) [Link]

For (1), I think kernel developers tend to consider pointers to structs of function pointers to be more clear than virtual functions, because it is easier to see exactly what has virtual functions and exactly what code fulfills each role in a particular case.

I haven't looked at Ingo's patch, but any problems which prohibited a compile-time solution in C (probably passing locks of unknown implementation through another function) would also prohibit it in C++, and C++ would then general virtual function calls, which would then be prohibitively expensive for such fast-path code. The reason for doing that sort of ugly thing is really that you have a special case with critical performance, and you have to open-code such things in any language.

C++ does have some advantages in type-checking, but C compilers warn about cases where these checks are either impossible or are violated, with the exception of some of the C++ checks which are actually detrimental. Sparse also does better type-checking than C++ supports, since it allows project-defined special conditions (like typed pointers to values in a different address space).

Actually, now I'm curious as to how hard it would be to get sparse to support "struct list_head * __of(struct dcookie_struct)" and type-check that like C++ templates or Java generic types.

Quote of the week

Posted Dec 9, 2004 21:29 UTC (Thu) by simlo (subscriber, #10866) [Link]

I haven't looked at Ingo's patch, but any problems which prohibited a compile-time solution in C (probably passing locks of unknown implementation through another function) would also prohibit it in C++, and C++ would then general virtual function calls, which would then be prohibitively expensive for such fast-path code. The reason for doing that sort of ugly thing is really that you have a special case with critical performance, and you have to open-code such things in any language.

Ofcourse you wouldn't do it by virtual functions in C++! You use virtual methods when you want to branch out run-time, not compile time. In C++ you simply define two classes with the same public methods. In this case class spinlock and class mutex with public methods lock() and unlock(). Then all code can compile with no further change no matter if you declare your lock by "mutex mylock;" or by "spinlock mylock;". The compiler sees a object with a lock() method and calls the right one (might be inlined). No branching at all. If you then want a flat function interface which matches the current one you can make a very simple templates to generate lock() and unlock() functions.

The way Ingo have done it in flat C is by doing making a macro containing "if(TYPE_EQUAL(lock), mutex) lock_mutex((mutex_t*)lock) else if(TYPE_EQUAL(lock, raw_spinlock_t)...." I know, with -O2 this wont actually generate a branching code but it is very, very ugly.

C++ is a huge benifit to people who know C++. It will _not_ make inefficient code unless you use it the wrong way ofcourse (see the above examble). On the contrary you can do more efficient code since you can do a lot of the stuff compile time. But to avoid complexity stay away trying smart templates combined with operator overloading. THAT is hell figure out when it can't compile. On the other hand when it can compile there are very few errors in the resulting program due to the strong type-checking.

Quote of the week

Posted Dec 13, 2004 7:10 UTC (Mon) by hppnq (guest, #14462) [Link]

Well, think of it as a work of art. You probably wouldn't have immediately recognized David when Michelangelo started hammering away. I'm quite confident that this will all be forgotten once Ingo has hammered a bit more.

As a side note, ugliness is not necessarily bad, because it will keep urging people to fix the associated problem.

Open-code?

Posted Dec 14, 2004 19:41 UTC (Tue) by Max.Hyre (subscriber, #1054) [Link]

What does ``open-code'' mean in this context? So far, I've not run across anything that would fit this use.

Of course, I tried Google:
"open code" -"open source" -"free software",
but was swamped with Free-Software-ish links anyway. :-)

Open-code?

Posted Dec 14, 2004 21:06 UTC (Tue) by iabervon (subscriber, #722) [Link]

Write out the full code that the convenient syntax would stand for, so that you can apply some optimizations based on information the compiler wouldn't have. So rather than having a C++ virtual method or using a function pointer, you'd actually write out tests and calls for all of the functions it could be, because the time to call a function pointer would be significant.

Quote of the week

Posted Dec 10, 2004 12:40 UTC (Fri) by kleptog (subscriber, #1183) [Link]

1) Instead of using pointers to a struct of function pointers use virtual functions in C++. What will actually happen runtime will be the same.

There is actually one thing pointers to functions can do that virtual functions can't, and that is be modifed at runtime. For example, you load a module that looks up the ops for UDP sockets and switches one for itself. In C++ the indirection is fixed by the type. Virtual functions would only work if you created the object of the right type in the first place, you can't affect existing objects.

Individual object can define their own callbacks setting a pointer. In C++ you acheive the same affect by deriving a new class for each possibility. The compiler needs to know at compile time all possible variations of that class.

Note, some other languages do allow run-type retyping including Perl and Python.

At least in C you can assume that the only operators that work on your own types are &, -> and .(dot). If none of those are involved you know you're only dealing with base or pointer types, whose rules are very simple.

Quote of the week

Posted Dec 11, 2004 12:51 UTC (Sat) by mmutz (guest, #5642) [Link]

The compiler needs to know at compile time all possible variations of that class.

If this is true, please explain to me how on earth the compiler manages to compile this code:

 
foo.h: 
class Foo { 
public: 
  virtual void f(); 
}; 
 
foo.cpp: 
#include "foo.h" 
void Foo::f() {} 
 
bar.h: 
#include "foo.h" 
class Bar : public Foo { 
public: 
  void f(); 
}; 
 
bar.cpp: 
#include "bar.h" 
void Bar::f() {} 
using something like
cc -o foo.o -c foo.cpp 
cc -o bar.o -c bar.cpp 
cc -o foobar foo.o bar.o 

Quote of the week

Posted Dec 11, 2004 17:23 UTC (Sat) by simlo (subscriber, #10866) [Link]

Make the examble better by making f pure virtual in the base class: Then you eliminate the problem of uninitialized function pointers compile time! C++ will simply not allow you to initialize an object of this class before a method have been specified.

By having structures of function pointers there is no check on the actual pointers point to anything sensible. The only thing safe to do is to check if they are non-NULL before using them! Waste of instructions...

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds