June 5, 2013

C++ rants (continued)

(link)

>Care to write an explicit example of a deep problem? (Except memory management - you already mentioned garbage collection.)

Concurrency, for example.

My point being, that C++ adds absolutely nothing interesting.

>All right. Then why do you think C should have support for structures (struct {...})?

That's just singularly stupid.

C is a good language. It's complete enough (and yes, the ability to handle structured data is very much required for any serious language) to be supremely useful, while at the same time being quite simple.

A language without structured data types would not be a powerful language the way C is. You do need data structures, and you need pointers (to both data and code) to be at all interesting.

But where do you draw the line?

I know that you as a C++ proponent you probably won't really "get" this simple argument, but try:

- read the K&R book on C (the ANSI edition), and be enlightened.

Notice how the language is basically described by one rather thin book. Readably.

So what C does so well is to do that whole "make it as simple as you can, but no simpler". And that is what makes it great. The language is powerful, yet fairly minimal.

There really aren't many features you could remove from the C language without crippling it. Sure, there's
three different looping constructs, and you could make trivial (syntactic) changes to the language, but that's
really not the point. The language is simple, but without being too simple.

Now, that's not what you always want. I understand very well why people want less system-oriented languages with more built-in functionality. As mentioned, support for both garbage collection and concurrency are quite real problems, and they are both things you can do in C, but that you cannot do well with library interfaces, which is how you normally would extend on C.

And garbage collection and concurrency are way more than just syntactic extensions. You can still do them very badly, of course, so it's not a trivial path to go down, and I'm not saying hat a language magically becomes "good" just from supporting one or the other.

But again: C does what it does very well, and with a clarity of thought and design that is entirely and utterly lacking from C++.

And yes, I happen to think that clarity of thought and design is a good thing. It's why I liked UNIX, even though I was initially introduced to other things (VMS - ugh).

C++ is a mess. There's no design. It's just "add crud on top of C". And the crud isn't even meaningful, much less does it have a design. It's totally and utterly random.

It started out random, now it's randomness that gets added to by a committee.

>For example, namespaces and function overloading are *not*
>useless. They *do* solve a real problem that C is incapable
>of solving.

You're full of it.

>For example, if you want in your source code to define a
>function called "connect" and you also want include
>"sys/socket.h", you cannot do that in C.

So to prove how it's not just a syntactic feature, you start talking about syntax?

What drugs are you on?

The name overloading is a total syntactic feature. In C, the way you fix your problem is by a totally trivial syntactic change: you call your function "my_connect()".

Wow. It's like magic. I added three characters, and made your whole reason for the crap that is C++ go away.

The thing is, the above is a really good example of why C++ is horrible, and why C is so simple.

Yes, the C solution is really simple. It's so simple that it looks downright stupid. But it's actually so simple that it is smart because quite frankly, it's a lot easier to get confused in C++ code, when the same function name means totally different due to overloading.

Of course, you're not "supposed" to overload things in confusing ways, but the thing is, just do what C does: just make your function names unique. It's not that hard, and by avoiding the overloading mess, you make it a lot easier to search for (hey look! "grep -w my_connect" just works!), and you avoid ambiguity.

(Same exact thing goes for your other example: just add a module prefix or have some other trivial naming rules for your functional split-up, and be happy)

Linus

C++ rants

By Linus Torvalds:

On Wed, 5 Sep 2007, Dmitry Kakurin wrote:
>
> When I first looked at Git source code two things struck me as odd:
>1. Pure C as opposed to C++. No idea why. Please don't talk about portability,
>it's BS.

*YOU* are full of bullshit.

C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it, to the point where it's much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out, that in itself would be a huge reason to use C.

In other words: the choice of C is the only sane choice. I know Miles Bader jokingly said "to piss you off", but it's actually true. I've come to the conclusion that any programmer that would prefer the project to be in C++ over C is likely a programmer that I really *would* prefer to piss off, so that he doesn't come and screw up any project I'm involved with.

C++ leads to really really bad design choices. You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap, that may "help" you program, but causes:

 - infinite amounts of pain when they don't work (and anybody who tells me that STL and especially Boost are stable and portable is just so full  of BS that it's not even funny)

 - inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app.

In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C. And limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that do actually understand low-level issues and don't screw things up with any idiotic "object model" crap.

So I'm sorry, but for something like git, where efficiency was a primary objective, the "advantages" of C++ is just a huge mistake. The fact that we also piss off people who cannot see that is just a big additional
advantage.

If you want a VCS that is written in C++, go play with Monotone. Really. They use a "real database". They use "nice object-oriented libraries". They use "nice C++ abstractions". And quite frankly, as a result of all these design decisions that sound so appealing to some CS people, the end result is a horrible and unmaintainable mess.

But I'm sure you'd like it more than git.

Linus

=====

Heath Provost (galvanash@hotmail.com) on 6/5/10 wrote:
>
>As for C++ exceptions - the same thing really applies here.
>They are trying to write explicit code. Exceptions are the
>poster child for implicit magic...

Yes, exceptions is a good example. The Linux kernel actually does its own exception mechanism, exactly because that way we control what is going on (and do it much more targeted to the actual need in question while giving much better performance and avoiding the crazy unwinding issues).

And I really do dislike C++. It's a really bad language, in my opinion. It tries to solve all the wrong problems, and does not tackle the right ones. The things C++ "solves" are trivial things, almost purely syntactic extensions to C rather than fixing some true deep problem.

(The C++ objects, templates and function overloading are all just syntactic sugar. And generally bad syntax at that. And C++ actually makes the C type system actively worse.)

In non-systems programming, you should almost certainly use a language that offers garbage collection. That will possibly make a real difference in the complexity of your application. The C++ features? Largely useless, and just helps you screw up more.

And in systems programming, you're simply better off with C. You'll have a way easier time using all the existing code and libraries out there (re-using C++ code? Good luck). Fewer headaches, fewer opportunities to mess up the design and pick some unstable template library.

So in neither case is C++ likely the right choice.

Linus


June 4, 2013

excerpt from "effective c++"

   
Cpp is like some stubborn old man, who always says "i have lots of obscure habits, dealing with it"......

Lesson 4: the initialization is different from assignment, as well as their representations respectively. It is better to write the constructor as the form of initialization, named "initialization list", rather than just simply give the variables first assignment.

To avoid using objects before they're initialized, then, you need to do only three things. First, manually initialize non-member objects of built-in types. Second, use member initialization lists to initialize all parts of an object. Finally, design around the initialization order uncertainty that afflicts non-local static objects defined in separate translation units.

Lesson 7: declare destructors virtual in polymorphic base classes. C++ specifies that when a derived class object is deleted through a pointer to a base class with a non-virtual destructor, results are undefined. What typically happens at runtime is that the derived part of the object is never destroyed. Eliminating the problem is simple: give the base class a virtual destructor. Then deleting a derived class object will do exactly what you want. It will destroy the entire object, including all its derived class parts.

The purpose of virtual functions is to allow customization of derived class implementations. Any class with virtual functions should almost certainly have a virtual destructor. The implementation of virtual functions requires that objects carry information that can be used at runtime to determine which virtual functions should be invoked on the object. On the other hand, if a class does not contain virtual functions, that often indicates it is not meant to be used as a base class. When a class is not intended to be a base class, making the destructor virtual is usually a bad idea.

Lesson 9: Never call virtual functions during construction or destruction. Because during base class construction of a derived class object, the type of the object is that of the base class. Not only do virtual functions resolve to the base class, but the parts of the language using runtime type information (e.g., dynamic_cast (see Item 27) and typeid) treat the object as a base class type.

The same reasoning applies during destruction. Once a derived class destructor has run, the object's derived class data members assume undefined values, so C++ treats them as if they no longer exist. Upon entry to the base class destructor, the object becomes a base class object, and all parts of C++ treat it that way.

Since you can't use virtual functions to call down from base classes during construction, you can compensate by having derived classes pass necessary construction information up to base class constructors instead.

Days of our lives

Daisypath Anniversary tickers