That's true, but it does enable me to have a LfbOut and a SerialOut and switch between them at runtime.Kevin wrote:Not sure if this is the best example for the usefulness of inheritance. You have one derived class per architecture in the source code, so what ends up in the binary (which is architecture specific) is exactly one implementation. You can certainly handle this without inheritance or any C++ - just link the the right putchar.o for the architecture. And you even save the overhead of virtual functions if you do without inheritance.
The C versus C++ debate
Re: The C versus C++ debate
This is not a productive area of discussion
Re: The C versus C++ debate
Well, but that's the way how "it's done" in C++. It is natural and unambiguous to use operator<<() for C++ output. Overloading operator<<() allows the implementor of a class to enable the system to print that class, instead of you having to extend printf() (in non-standard ways, too). There are more reasons (e.g. type safety), but in the end it boils down to the old saying:rJah wrote:Which is why I don't overload << in my output stream, I always found the "shift stream left" kind of strange.Solar wrote:Overload operators only where it would feel natural and unambiguous to do so, and nowhere else,
Real programmers can write FORTRAN in any language.
Every good solution is obvious once you've found it.
Re: The C versus C++ debate
Right, this is a much better example.rJah wrote:That's true, but it does enable me to have a LfbOut and a SerialOut and switch between them at runtime.Kevin wrote:Not sure if this is the best example for the usefulness of inheritance. You have one derived class per architecture in the source code, so what ends up in the binary (which is architecture specific) is exactly one implementation. You can certainly handle this without inheritance or any C++ - just link the the right putchar.o for the architecture. And you even save the overhead of virtual functions if you do without inheritance.
Re: The C versus C++ debate
That was a perfect example of what not to do in the kernel... virtual functions. Granted, some people really don't care about performance, if that's the case, go for whatever is easier then, just don't expect miracles when you start benchmarking your kernel against others . You do realize you could just as easily store a pointer to your current putChar right? Or even something like setting a default output device. I currently have all my serial devices in my VFS, and I can easily toggle my output between the screen and serial port without virtual functions, while still being perfectly readable. I am more from the performance side of the house... but everything in OS dev is a tradeoff. How much performance vs. readability/safety are you willing to sacrafice. There is no correct answer. I could write my OS in asm (and have written an os in asm)... development was slow, code wasn't as easily followed, not very likely that I could port it to another system, etc. But, it sure was fast, small and efficient .
Re: The C versus C++ debate
*that's exactly what virtual functions ARE*.Ready4Dis wrote:That was a perfect example of what not to do in the kernel... virtual functions. Granted, some people really don't care about performance, if that's the case, go for whatever is easier then, just don't expect miracles when you start benchmarking your kernel against others . You do realize you could just as easily store a pointer to your current putChar right?
Try using a profiler next time. Or code analysis.I am more from the performance side of the house...
Re: The C versus C++ debate
I've done both, and I can say for 100% certainty (after a good amount of benchmarking thank you) that having a class full of virtual functions vs. a single device pointer is much slower. Yes, virtual functions ARE pointers, congratulations, you made it past C++ 101... Anyways, I'm not going to argue, just re-iterate what I've said. If you don't care about performance, and just want code readability (which he clearly stated he preferred), then go for it. The overhead of virtual functions, especially in higher level functionality is minimal, it's when people start abusing it in inner loops that require speed that the difference really shines. If the person knows how to use it, and when to use it, you can minimize the performance hits, which I and others have already stated. If you bothered to read his code, instead of just try to jump down my throat about how a virtual function is a pointer, you'd realize how inefficient his IOOutputStream class is. Firstly, in order to support multiple devices, he'd still need an array, or list of output streams... there's MY device pointer reference. Now, EACH of those streams has a set of virtual functions, which has an extra memory lookup to perform. If he calls printf, then calls putChar... that's another extra lookup. Yes, for an iostream, who cares, I'm sure it'll print to the screen plenty fast enough, but in general (unless you are VERY careful) virtual functions end up adding extra code, and slowing things down (how badly, and how much the effect depends on what ti's being used for).Candy wrote:*that's exactly what virtual functions ARE*.Ready4Dis wrote:That was a perfect example of what not to do in the kernel... virtual functions. Granted, some people really don't care about performance, if that's the case, go for whatever is easier then, just don't expect miracles when you start benchmarking your kernel against others . You do realize you could just as easily store a pointer to your current putChar right?
Try using a profiler next time. Or code analysis.I am more from the performance side of the house...