The worst kind of projects are the ones that have islands of code written in random and widely differing styles.
The C versus C++ thing has been discussed to death before. Read Linus Torvalds' take on it. He's not very diplomatic, but he is right. In short, object orientation isn't a language feature; it's a programmer feature.
It would be nice if gimp were somehow a set of C modules controlled by, say, a python GUI. That would also allow people to write scripts that made new and interesting programs out of the basic components. I know that gimp is scriptable now, but I'm thinking of something that goes well beyond that.
Posted Jan 12, 2011 9:58 UTC (Wed) by romanfi (guest, #72329)
[Link]
mccabe wrote:
> object orientation isn't a language feature; it's a programmer feature
That's like saying "as long as it's possible to put nails into the wall by hand, why using a hammer?".
A language has to support common and daily tasks to be done by programmers. The kernel is full of object oriented designs like inheritance, virtual functios, namespaces, inline functions, member functions, member access, etc., why not using a hammer?
Of course, I also know people and designs who try to do every thing object oriented, drawing bubbles around everything they can find, and the connecting them via funny lines with arrows and bars. That's not the way I'd like to see C++ in the kernel, more the way I use it since g++ supports C++ and we were using C++ for embedded designs a lot, even down to standalone code in very fast boards e.g. inside FlexRay data loggers. No new/delete from libc++ but own implementations, no artificial inheritance or virtual functions with pointer arrays, simple and readable code, not overdoing it.
Not everything is a nail...
Posted Jan 13, 2011 13:50 UTC (Thu) by khim (subscriber, #9252)
[Link]
The kernel is full of object oriented designs like inheritance, virtual functios, namespaces, inline functions, member functions, member access, etc., why not using a hammer?
Because not everything is a nail? Seriously: take a look on how kernel does thing and you'll see that C++ design will be more complex and much less flexible. C++ is great hammer but it's still a hammer. If you use C++ then you tend to think that every problem is a nail and this leads to truly ugly code.
Today's C++ (especially C++ 200x in GCC 4.5+) includes more then hammer, but it's still quite hard to use right (and the code produced in C++ is usually significantly more resource-hungry and slower then code written in C), but 10 years ago it was a joke.
I think it's good idea to use C++ for things where there are not enough developers ("bloated and slow, yet working program" is still better then lead and mean program which "will be delivered RSN for the last 10 years"), but for kernel C++ is bad choice.
Not everything is a nail...
Posted Jan 14, 2011 4:55 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
Because not everything is a nail? Seriously: take a look on how kernel does thing and you'll see that C++ design will be more complex and much less flexible. If you use C++ then you tend to think that every problem is a nail and this leads to truly ugly code.
Everything that can be done in C can be done at least as well in C++. Claiming that C++ would have led to a more complex and less flexible design is thus downright absurd. C++ is a multi-paradigm language that doesn't force any particular programming style down anybody's throat, and if doing things like in C provides advantages, C++ won't stop you.
(and the code produced in C++ is usually significantly more resource-hungry and slower then code written in C)
That's outright bullshit. A key design decision in C++ has always been "don't pay for what you don't use", and it worked out pretty well in fact.
Not everything is a nail...
Posted Jan 14, 2011 9:43 UTC (Fri) by dwmw2 (subscriber, #2063)
[Link]
The problem in the kernel is that we get a lot of drive-by contributions from people who don't really know what they're doing. A lot of driver code is pure crap.
You are absolutely right that C++ can be used sparingly. Qt handles it fairly well, enforcing a sane use of a subset of C++ rather than the whole range of features.
However, this does depend on restraint on the part of the developers. If we had C++ available, we would either spend a lot of time telling developers "no, you can't do that", or we'd accept a lot of use of C++ features that we would prefer not to use.
It is often the case that certain developers don't have a full understanding of the cost of the code they're writing, even when they're using C. Not everyone is forced to spent part of their life looking at the compiler output from their code and seeing what it actually does, although they ought to be.
While the "don't pay for what you don't use" principle has indeed worked out pretty well in general, the fact remains that people would be using more, and thus paying more. Unless you just want us to compile our existing C code with a C++ compiler? :) Which wouldn't work today because we make heavy use of C99 structure initialisation, and I don't believe that works in C++?
Not everything is a nail...
Posted Jan 21, 2011 15:56 UTC (Fri) by daglwn (subscriber, #65432)
[Link]
It is often the case that certain developers don't have a full understanding of the maintenance cost of the code they're writing,
I am sick and tired of kernel people spouting ignorance about C++. They look like fools. Every single project I've followed that places restrictions on the use of C++ ends up with bugs and misdesigns that could have been avoided had the leadership opened its minds to the idea that C++ is a cohesive language. Stripping parts of it out just means you're throwing away safety, code reuse or both.
Not everything is a nail...
Posted Jan 21, 2011 20:31 UTC (Fri) by xilun (subscriber, #50638)
[Link]
And only work with C++ experts in any cases (restrictions or not). Who are even more difficult to find than C experts, and C experts are already difficult enough to find...
Not everything is a nail...
Posted Jan 21, 2011 23:41 UTC (Fri) by daglwn (subscriber, #65432)
[Link]
I really question whether competent C++ developers are hard to find. There are lots of C++ jobs out there so it's not as if the language isn't being used. You really have to try _not_ to learn something about a language after using it for a while.
In my experience the problem is resistance to the unknown, no matter how much that unknown might improve one's productivity.
Not everything is a nail...
Posted Jan 21, 2011 21:46 UTC (Fri) by Spudd86 (guest, #51683)
[Link]
The problem is that many C++ features would need additional support code that doesn't currently exist in the kernel (for example, exception handling with zero overhead in the case of no exceptions thrown would need both new kernel code to support it and tighter coupling between the kernel and compiler).
In the kernel restrictions are more than just style or taste, they are also because the user space code that the compiler relies on being present in the final executable may not work in kernel space, if it doesn't that feature either cannot be used or replacement support code must be written, the latter option ties the kernel more tightly to the compiler and increases the chances that a new compiler version will break the kernel.
Not everything is a nail...
Posted Jan 21, 2011 23:52 UTC (Fri) by daglwn (subscriber, #65432)
[Link]
Of course something like exceptions would require support code in the kernel and I'm not advocating that exceptions are necessarily the best way to do error handling in the kernel. I'm not an expert in the kernel domain so I don't feel qualified to judge either way. The same goes for rtti, which can often be avoided anyway.
What I am advocating is that the kernel people unplug their ears, uncover their eyes and think about what benefits C++ might bring. It would help tremendously with writing code that uses callbacks. The whole filesystem architecture with the VFS layer and implementation layers is crying out for an inheritance model. RAII would help a lot with resource cleanup.
Heck, RAII *alone* should be enough to seriously consider C++ in any project.
Now rewriting the filesystem architecture is too much to expect (I'm just giving it as a well-known example) but these kinds of patterns abound in most code. C++ really can save a lot of lines of code and that usually means fewer bugs and often better performance.
But the trick is, you have to use the multi-paradigm features of the language. Multiple inheritance, templates, operator overloading and constructors/destructors complement each other in surprisingly beautiful ways. I have heard strong arguments against all of those features and I just shake my head in sadness every time I have to address them.
Not everything is a nail...
Posted Jan 22, 2011 0:52 UTC (Sat) by jmm82 (guest, #59425)
[Link]
The VFS already has an inheritance model in c, it is called function pointers.
Not everything is a nail...
Posted Jan 22, 2011 1:25 UTC (Sat) by daglwn (subscriber, #65432)
[Link]
Which is, of course, my whole point. Why go through the pain and bugs involved with function pointers when the compiler will generate it for you? It baffles me why anyone who advocates using tools to automate tasks (i.e. anyone who writes code) would abandon that principe at some arbitrary level of the development stack.
Not everything is a nail...
Posted Jan 25, 2011 9:38 UTC (Tue) by paulj (subscriber, #341)
[Link]
You can do RAII in C just fine...
Not everything is a nail...
Posted Jan 25, 2011 16:06 UTC (Tue) by jrn (subscriber, #64214)
[Link]
I suppose it depends what RAII means. But no, I am not aware of a simple way to, say, free memory on the heap when a pointer to it falls out of scope (especially when a "return" statement exits that scope).
Not everything is a nail...
Posted Jan 25, 2011 16:41 UTC (Tue) by etienne (subscriber, #25256)
[Link]
Maybe you do not have the problem of freeing memory when a local structure goes out of scope in C (outside of kernel space), because in that case the local structure is declared in the stack and will be freed automatically...
Maybe the real problem is that your "autoptr" is not able to manage an object in the stack, but you need an "autoptr" because one method has such an argument.
Not everything is a nail...
Posted Jan 25, 2011 22:18 UTC (Tue) by daglwn (subscriber, #65432)
[Link]
Will that local structure also close files for me when it goes out of scope? Or does that local structure free memory pointed to by members of that structure when it goes out of scope? Or does that local structure release a lock it holds when it goes out of scope?
RAII is about MUCH more than memory.
Not everything is a nail...
Posted Jan 26, 2011 12:32 UTC (Wed) by paulj (subscriber, #341)
[Link]
For me RAII in the abstract is an object/resource-lifetime management strategy, such that creation and destruction of composite objects appear atomic wrt resources/objects held internally, as far as users of the object are concerned. Obviously it's good programming to try make objects atomic in this way when designing code.
C++ has implicit calls to constructors and destructors, which tie in to scoping. C doesn't have that, true, and requires explicit construction and destruction (you can still hide destruction behind refcounting, obv). It's often bad practice and/or a sign of a (quick)? hack when C code uses automatic allocating for non-trivial, composite objects.
Whether language support for implicit ctor/dtors tied with scoping is required for a practice to be called RAII, I don't know. I guess to a C++ person it does. Still, the general sentiment of RAII seems more widely applicable than C++.
Not everything is a nail...
Posted Jan 26, 2011 19:52 UTC (Wed) by daglwn (subscriber, #65432)
[Link]
Implicit destruction (finalization, uninit or whatever you want to call it) seems to me integrally tied to the concept of RAII. Without it, one ends up having to cover all exit points of a scope with explicit calls to cleanup code. Either this means there are several such calls scattered around parts of the enclosing scope or there's a big ugly goto to a common piece of cleanup code. Neither is particularly attractive or maintainable.
This gets to be impossible if the exit points are not known statically. C++ exceptions are a classic example but since some seem to think the C++ exception model is broken, I will emphasize that the problem is NOT solved by eliminating exceptions. One still has to cover all exit points with cleanup code.
Perhaps a better term for this would have been "resource ownership is object lifetime."
Not everything is a nail...
Posted Jan 30, 2011 0:37 UTC (Sun) by nix (subscriber, #2304)
[Link]
*Closures* would help tremendously in writing code that uses callbacks. But they require quite a lot of runtime support which is not available in the kernel.
C++'s syntactic sugar is insignificant in comparison. (At least, in this area. I agree that RAII is really nice, but the kernel seems to be surviving without it.)
Well, it's quite simple, really...
Posted Jan 18, 2011 11:34 UTC (Tue) by khim (subscriber, #9252)
[Link]
Everything that can be done in C can be done at least as well in C++.
Well, this is strawman argument: of course you can just ignore all C++ extensions and then produce the same code in C++ as in C. But what's the point? If you try to use "real" C++ facilities...
$ cat hello.c
#include <stdio.h>
int hello() {
printf("Hello, World!\n");
}
$ gcc -O3 -c hello.c ; size hello.o
text data bss dec hex filename
72 0 0 72 48 hello.o
$ cat hello.C
#include <iostream>
int hello() {
std::cout << "Hello, World!" << std::endl;
}
khim@khim-glaptop:/tmp$ gcc -O3 -c hello.C ; size hello.o
text data bss dec hex filename
244 8 1 253 fd hello.o
Claiming that C++ would have led to a more complex and less flexible design is thus downright absurd.
Not really. Most C++ designs are indeed more flexible, but this is not a big factor for kernel development where you can always redesign anything (the infamous "stable API nonsense"), but the fact that they are "more flexible" usually means they are more complex and less efficient.
(and the code produced in C++ is usually significantly more resource-hungry and slower then code written in C)
That's outright bullshit. A key design decision in C++ has always been "don't pay for what you don't use", and it worked out pretty well in fact.
Where "pretty well" == "bloat of about factor of two or three". Yup. C++ does not impose choice on your so you end up with 4-5 implementations for basic things. Heck, C++ standard includes two different string implementations from the start (I mean "char *" and "std::string") - and different libraries like to add additional ones! And we are talking about kernel, remember? Kernel shares L1 with userspace program and it's pitiful: 64K at most. And, please, don't talk about Moore's Law here: PowerPC 601 had 32K cache 18 years ago, Intel Core2 has 32K cache today. Yeah, it's kind of "apples vs oranges" because there are two 32K caches on Core2 and PowerPC 601 and AMD's Phenom has whopping 64K L1 cache, but anyway: even two doublings per 18 years is not enough to claim that endless adapters and transformers are no longer meaningful for kernel.
The "don't pay for what you don't use" is only good when you don't use anything. When you actually do use some facilities you suddenly find out that they cost more then in case where language imposes things on you.
Well, it's quite simple, really...
Posted Jan 18, 2011 12:08 UTC (Tue) by dwmw2 (subscriber, #2063)
[Link]
"Well, this is strawman argument: of course you can just ignore all C++ extensions and then produce the same code in C++ as in C."
Can I? In the kernel we make heavy use of C99 structure initialisation. Where structures can so often change and gain new members, it's very important to have named initialisers. But this code will fail if compiled as C++:
struct foo {
int a;
int oh_we_introduced_this_optional_thing_later;
int b;
};
struct foo f = {
.a = 1,
.b = 2,
};
Losing that facility would introduce a lot of errors into the kernel, at a single fell stroke.
Well, it's quite simple, really...
Posted Jan 18, 2011 13:27 UTC (Tue) by foom (subscriber, #14868)
[Link]
Surprisingly, it didn't even make it into C++0x.
It seems to me it'd be a reasonable extension for "gnu++0x", though.
Well, it's quite simple, really...
Posted Jan 18, 2011 18:57 UTC (Tue) by daniel (subscriber, #3181)
[Link]
The lack of designated initializers in C++ is pure brain damage. I do not understand why the issue does not get more attention. That said, the old gnu syntax still works: {foo: x, bar: y} except that you have to specify the initializers in the order declared and insert nulls if you skip fields, the latter requirement serving no imaginable purpose whatsoever. But at least in this way you can protect yourself from structure field evolution. This C advantage in no way makes up for all the structuring primitives that C lacks.
Well, it's quite simple, really...
Posted Jan 18, 2011 21:07 UTC (Tue) by foom (subscriber, #14868)
[Link]
It doesn't sound like brain damage, but rather a brand new (well, 12 years old now, but by C standards, brand new) feature in C that has not been ported to C++ yet. C++ adds all sorts of additional complex interactions to such a feature that would have to be properly specified...and nobody's done that yet. You could probably get a proposal accepted for C++20 (or whatever) though...
The restrictions on the GCC extension seem like someone just didn't really finish implementing it yet. I'd bet you would be welcome to do so.
Sobotka: Why GIMP is inadequate
Posted Jan 12, 2011 15:15 UTC (Wed) by HelloWorld (guest, #56129)
[Link]
The C versus C++ thing has been discussed to death before. Read Linus Torvalds' take on it. He's not very diplomatic, but he is right. In short, object orientation isn't a language feature; it's a programmer feature.
This is a bogus argument for two reasons. Firstly, C++ does not equal C+OOP. Even if C++ didn't have any support for OOP, it'd still be worth using because of features like templates, namespaces, RAII and all that. Secondly, an object-oriented design will look much, much cleaner and be more maintainable in C++ than in C.
Sobotka: Why GIMP is inadequate
Posted Jan 13, 2011 10:17 UTC (Thu) by paulj (subscriber, #341)
[Link]
C may have limitations and deficiencies relative to modern programming concepts - I could accept that. However, how does it follow that the answer to this is C++, as the original commentator suggests? C++ perhaps has *even more* deficiencies than C, relative to modern programming concepts and other (often necessarily more recent implementations)? Let's look at your list:
Templates: These are a bodged implementation of generic/meta types (perhaps not C++'s fault, as generic/meta types were prototyped in C++ to an extent). Due to different instantiations of the same template literally copying the code, they're hell on I-caches - spectacularly inefficient. Due to its implementation roots as code that's inserted in a pre-processor phase, producing compilation error messages that don't look like incomprehensible gobbledygook to anyone but C++ compiler developers and/or language spec committee members can be challenging. At least one widely used C++ compiler still fails terribly at this.
RAII: This is a programming pattern popularised, in large part, because of the *deficiencies* of C++, wrt the many subtle ways exceptions interact with other parts of the C++ language spec (construction and deconstruction particularly). Further, you *can* quite easily (if you're adhering to OOP) do RAII in C, as I'm sure you must know.
Namespaces: Ok, I grant you that one. But there are other choices of language, beside C++, with namespacs. ;)
Then there are all the other problems with C++...
So, again, if you got fed up with C and wanted to switch to a better language for some large, high-level user-space project (e.g. GUI graphics processing app), why on earth would you choose C++? Surely C#, Java, or Vala, perhaps others, would be a much better choice? For the low-level, C beats C++. For the high-level, with the rise of much cleaner languages that have learned from C++ mistakes and have not been saddled by its baggage, has C++ not had its day?
Sobotka: Why GIMP is inadequate
Posted Jan 13, 2011 11:33 UTC (Thu) by boudewijn (subscriber, #14185)
[Link]
"However, how does it follow that the answer to this is C++, as the original commentator suggests?"
Where did I suggest that? A big C project that uses GObject is awfully difficult to get into for a newbie.
Heck, I have spent more than once several weeks getting people up to speed with Qt and C++ so they could contribute to Krita (and C++ with Qt is awfully close to Java for a beginner) so I know that "C++" isn't the answer. I think there is no answer for Gimp -- but that doesn't mean it isn't a problem.
Spending that time on beginners has almost always been worth it, by the way, with the newcomers becoming valued members of the development team and producing awesome stuff.
Sobotka: Why GIMP is inadequate
Posted Jan 19, 2011 21:36 UTC (Wed) by DOT (subscriber, #58786)
[Link]
"Heck, I have spent more than once several weeks getting people up to speed with Qt and C++ so they could contribute to Krita (and C++ with Qt is awfully close to Java for a beginner) so I know that "C++" isn't the answer. I think there is no answer for Gimp -- but that doesn't mean it isn't a problem."
Since Vala is embarassingly compatible with C and GObject, it should be possible to write new code in that language where appropriate.
But honestly, I think the problem is not in the code. You'll only have to look at LibreOffice and its awesome community to know that code doesn't really matter. I would start looking for the problem somewhere in human department.
Sobotka: Why GIMP is inadequate
Posted Jan 13, 2011 11:53 UTC (Thu) by HelloWorld (guest, #56129)
[Link]
> C may have limitations and deficiencies relative to modern programming concepts
That seems to be an understatement ;)
> Templates: These are a bodged implementation of generic/meta types
They're not. Stroustrup knew about ML (which had generics all along) when he designed C++, but he deliberately designed templates differently. ML-style generics require a boxed data representation and can't properly deal with stuff like overloaded assignment operators, and you can't specialize them. Templates and generics are two very different beasts, even though they serve similar purposes.
> Due to different instantiations of the same template literally copying the code, they're hell on I-caches - spectacularly inefficient.
They're not, actually. Try sorting a million floating point numbers with std::sort and qsort. The std::sort version will be much faster, because in a function template, the comparison can be inlined, while in the qsort version, you have to call it through a function pointer, defeating the CPU's branch prediction.
Also, partial template specialization can be (and is being) used to reduce or eliminate copied code. For example, it is possible to specialize the vector<T> class so that if T is a POD type (POD = plain old data), a generic implementation based on memcpy etc. will be used and the template merely acts as a type-safe wrapper around it, the overhead of which can be trivially optimized away by the compiler.
> Due to its implementation roots as code that's inserted in a pre-processor phase, producing compilation error messages that don't look like incomprehensible gobbledygook to anyone but C++ compiler developers and/or language spec committee members can be challenging.
Cfront never was any sort of preprocessor, it always was a proper compiler which just happened to generate C code as that was the only way to achieve good portability back then.
I agree that template error messages are a problem, but it's not an easy one to fix. The problem is that the compiler can't know if a failed template instantiation is due to a bug in the template or due to the type parameter not satisfying the requirements of the template.
In Haskell, type classes solve a similar problem fairly elegantly. They tried to add a similar feature to C++0x but failed, so this problem will be with us for some time.
> RAII: This is a programming pattern popularised, in large part, because of the *deficiencies* of C++, wrt the many subtle ways exceptions interact with other parts of the C++ language spec (construction and deconstruction particularly).
Every language needs to deal with some form of resource cleanup, and RAII is a very elegant way to do so. The fact that one motivation for RAII was exception safety doesn't change that in the least. What other solution for the resource cleanup problem do you propose? A GC doesn't count as it only deals with memory. I found the "finally" blocks found in many languages to be much less useful.
> Further, you *can* quite easily (if you're adhering to OOP) do RAII in C, as I'm sure you must know.
As I'm sure you must know, there is no such thing as an implicitly called destructor in C. This makes the idiom much less useful than it is in C++.
> So, again, if you got fed up with C and wanted to switch to a better language for some large, high-level user-space project (e.g. GUI graphics processing app), why on earth would you choose C++? Surely C#, Java, or Vala, perhaps others, would be a much better choice?
Hey, I didn't propose to rewrite the Gimp in C++, did I? Anyway, comparing C# etc. to C++ is a red herring. C++ is a systems programming language, and it was always meant to be. Which leads us to the next point...
> For the low-level, C beats C++.
I disagree. Everything you can do in C can also be done in C++, and it'll be cleaner and more elegant. In fact, I flat-out hate C. It needs to die a gory death, and the sooner that happens, the better. It just doesn't do what I need it to do, not even for low-level programming.
Sobotka: Why GIMP is inadequate
Posted Jan 14, 2011 9:31 UTC (Fri) by paulj (subscriber, #341)
[Link]
Re templates: I don't know enough about the history of C++, but that to me sounds like C++ settled for a bodged version of generics because of implementation compromises. I'm not sure what you mean by 'specialise', do you mean extend the base functionality, or modify/remove it? If the former, generic type theory allows that, if latter then that's no longer safe according to standard type-theory, no (but then templates themselves aren't really types in C++ - part of the bodge)?
Caching: What you describe is the relative efficiency of function pointers, branch-prediction v I-cache. That's not a constant thing at all and varies a lot between processors and over time as processor technology changes. E.g. there's no fundamental reason why branch-prediction can not predict branches behind repeated calls to the same function pointer - that branch predictors in the past have not dealt well with function pointers doesn't mean this always is so. On the other hand, that templates put pressure on I-caches *is* a fundamental fact. It will always be a factor, so long as CPUs need I-caches.
RAII: C doesn't explicitly have support for implicitly calling a custom per-object deallocator on free(), but setting up the scaffolding to do this is half a days work, and there are existing allocator libraries that can make this even easier (e.g. talloc). If you lack the imagination to put a header in front of your allocated objects and populate it with useful function pointers, and override free(), well.... ;) That half-days-work is much shorter than the *years* it takes to discover all the subtle ways C++'s historical baggage and design decisions can bite the programmer. ;)
As for C#, Java, Vala, etc and rewriting the GIMP: this discussion about C v C++ started because people criticised GIMP for being in C and suggested C++ would be better. Where's the evidence for this claim? Even if we accept C++ has merits over C, exactly how does this make C++ the correct choice *today* for programming large, end-user applications? If the answer isn't C, then it surely isn't C++ either...
Sobotka: Why GIMP is inadequate
Posted Jan 14, 2011 15:00 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
Re templates: I don't know enough about the history of C++, but that to me sounds like C++ settled for a bodged version of generics because of implementation compromises.
They're not, and I already told you why: generics are less flexible and require a boxed data representation, at least in any implementation of generics I know of. And if templates were merely a sucky replacement for generics, why did the developers of the D language choose to implement templates as well?
RAII: C doesn't explicitly have support for implicitly calling a custom per-object deallocator on free(),
It's not about calling a custom deallocator on free but about implicitly doing something (like unlocking a mutex or decreasing a refcount) when an object leaves some scope. This needs some form of language support.
<ramblings about caching>
Well, if you think that qsort offers a better tradeoff than std::sort, you can still write an easier to use, type-safe wrapper.
template<typename T> int compare(const void *, const void *);
// implementation left as an exercise for the reader
template<typename T> void my_sort(T *base, size_t nmemb) {
return std::qsort(base, nmemb, sizeof(T), &compare<T>);
}
As for C#, Java, Vala, etc and rewriting the GIMP: this discussion about C v C++ started because people criticised GIMP for being in C and suggested C++ would be better. Where's the evidence for this claim? Even if we accept C++ has merits over C, exactly how does this make C++ the correct choice *today* for programming large, end-user applications? If the answer isn't C, then it surely isn't C++ either...
I think that reasons were given for preferring C++ to C (templates, OOP, RAII, namespaces); of course, you're free to disagree with these. I also didn't claim C++ is the right choice for an application like the GIMP if it were written today, and it probably isn't, as a low level language like C++ is probably a poor choice for a graphical app today. It merely annoys me when people like cmccabe keep trolling against C++ and do as if C were the holy grail of systems programming languages.
Sobotka: Why GIMP is inadequate
Posted Jan 14, 2011 16:29 UTC (Fri) by paulj (subscriber, #341)
[Link]
Generics have a sound body of type theory behind them though. Boxing types - I don't see a problem with that for OOP. And from what you say, the error-message problem is actually somewhat fundamental to templates. I really hate templates I have to say.
Re implicit destructors for automatic variables. True, that requires language support. OTOH, C++ allowing automatic storage objects is one of those things that lead to subtle corner-cases, ISTR...
Anyway, our opinions clearly differ. ;)
Sobotka: Why GIMP is inadequate
Posted Jan 14, 2011 18:32 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
Generics have a sound body of type theory behind them though.
C++ templates have been studied by type theorists too, see for example this paper.
Boxing types - I don't see a problem with that for OOP.
C++ is not only object-oriented, and in fact, containers are very often used for built-in types like int. Boxing these is ridiculously inefficient.
Re implicit destructors for automatic variables. True, that requires language support. OTOH, C++ allowing automatic storage objects is one of those things that lead to subtle corner-cases, ISTR...
Like what? I always found implicitly called destructors to be a boon. Much more so than, say, Java's finally blocks. Alas, YMMV and as you already said, we should probably just agree to disagree :).
Sobotka: Why GIMP is inadequate
Posted Jan 14, 2011 20:34 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
> And from what you say, the error-message problem is actually somewhat fundamental to templates.
A similar problem applies to dynamically typed languages like python though. The interpreter can't possibly know whether the type of a function argument satisfies the requirements of the function it is passed to. The difference being that a C++ compiler will point that out at compile-time, while a dynamically typed language won't throw up until run-time, much less give you a sensible error message.
Poor implementations are also part of the problem. g++'s error messages are worse than they could be, for example it always talks about std::basic_string<char, std::char_traits<char>, std::allocator<char> > instead of plain std::string (the latter being a typedef for the former). Clang++ is supposed to be much better at this, though I haven't tried it yet.
Sobotka: Why GIMP is inadequate
Posted Jan 18, 2011 20:06 UTC (Tue) by daniel (subscriber, #3181)
[Link]
"I really hate templates I have to say."
For me it's a love hate relationship. I love the way I can generate efficient code from terse, readable source. I hate the way compile errors get weirder and weirder, the the latter may be as much an implementation issue as anything. Templates are really just a highly automated form of cut and paste that allows you to create *maintainable* cut and paste code, and package it for general use.
The extent to which cut and paste code abuses the processor cache says more about the programmer than the mechanism. I use partially specialized templates to create efficient variant forms of low level graphical operations. The initial pure C code base I developed to do the same thing grew tendrils and degenerated to to an unmaintainable state rapidly so that working on it slowed down and became deeply unappetizing. After being recast as an orthogonal set of C++ templates the source code shrank by a multiple and I was able to add the sophisticated new capabilities that seemed only a distantly obtainable hope with the original C code base. The actual generated code hardly changed, just my ability to develop it.
Sobotka: Why GIMP is inadequate
Posted Jan 14, 2011 20:01 UTC (Fri) by cmccabe (guest, #60281)
[Link]
> On the other hand, that templates put pressure on I-caches *is* a
> fundamental fact. It will always be a factor, so long as CPUs need
> I-caches.
Indeed. I'm working on a large C++ project now, and this is a big problem for us. We use the STL heavily, especially the container classes.
Incidentally, if anyone here knows some good workarounds, they would be much appreciated! I know about the void pointer trick, but unfortunately most of our containers don't contain pointers; they contain class types.
Sobotka: Why GIMP is inadequate
Posted Jan 14, 2011 13:59 UTC (Fri) by dwmw2 (subscriber, #2063)
[Link]
Unconditional branches aren't so hard to predict, FWIW.
Sobotka: Why GIMP is inadequate
Posted Jan 16, 2011 21:11 UTC (Sun) by cmccabe (guest, #60281)
[Link]
I wrote a little test, and apparently std::sort *is* faster than qsort, at least at sorting an array of 4 million ints. My CPU is an AMD Phenom(tm) II X4 820.
In my opinion, templates are the best feature of C++. They're really the *only* feature I miss in C-land. You can use macros to accomplish the same thing in C. I vaguely remember that the BSD kernel has a header file implementing qsort-as-a-macro. However, it's less convenient.
Sobotka: Why GIMP is inadequate
Posted Jan 17, 2011 1:11 UTC (Mon) by jthill (guest, #56558)
[Link]
Glad to see somebody else sees them that way. The don't have to be all verbose and complicated, and if you collect the machinery they implement together in one spot and get the formatting right they can make things very much clearer.
Sobotka: Why GIMP is inadequate
Posted Jan 13, 2011 20:38 UTC (Thu) by daniel (subscriber, #3181)
[Link]
"He's not very diplomatic, but he is right. In short, object orientation isn't a language feature; it's a programmer feature."
If that is truly Linus's position then he is wrong, way wrong, irrespective of the fact that on LKML Linus is always right, by definition.