First, I'm not a very experienced programmer, but I know C and C++, maybe not the advanced stuff.

Since ID software released of the quake 3 source code, I was wondering why they used C instead of C++.

Is there a real advantage of working with plain C, meaning not dealing with abstract stuff ?

I know the object concept can be great, by I never really understood the real advantage of C++, since it depends of the programmer's way of solving a problem...

I already asked on a french forum (which was closed for reasons I don't really know, maybe they could not really answer, but apparently they did not like my tone, you know the french...)

Thanks for reading

Kenneth_Gorking
—
2010-05-10T16:42:13Z —
#2

The Quake3 engine has been progressively developed for a very long time. I remember reading an interview with some guy working at id (can't remember if it was Carmack), and he said that it still contains code from the original Doom game, which ran an very early version of the engine. The engine for Doom was again an improved version of the Wolfenstein 3D engine. C would have seemed like a better choice of language back then, I guess.

You can download the sourcecode for Doom, and compare for yourself

As for using C++ over C, features like templates and dynamic binding make it easier to use, imho.

fireside
—
2010-05-10T16:48:16Z —
#3

I think Carmack prefers c. OO programming does add a layer of abstraction, so it might be a little slower, depending how it's used. Most engines use c++ now because it's better for code organization and the speed difference is minimal.

vrnunes
—
2010-05-10T17:55:36Z —
#4

Some years ago C was still way faster than C++, because each processor clock cycle were very important.

martinsm
—
2010-05-10T18:42:37Z —
#5

Because C++ (standart, not the actual compiler!) was properly released only 1 year before release of Quake 3. If you take into account that developing it took 1 or 2 years, then you must undesrstand why they didn't choose C++.

Because C++ (standart, not the actual compiler!) was properly released only 1 year before release of Quake 3. If you take into account that developing it took 1 or 2 years, then you must undesrstand why they didn't choose C++.

C++ compilers existed well before the standard was released. Quake 1 was developed using DJGPP, which uses a DOS port of the GCC compiler, which was a pretty decent C++ compiler at the time. Quake 3 was developed using Microsoft Visual C++ 6, which, as the name suggests, also supported C++.

The reason they were using C was performance considerations and simply because "they've always been coding C".@tobeythorn

without message passing, c++ isn't really objected oriented anyway

I'm sorry, what?! The main pillars of object oriented programming are data abstraction, encapsulation, polymorphism, and inheritance. C++ supports all those features. Message passing has nothing to do with OOP per se. Sending/receiving messages and calling/being called by methods serve exactly the same purpose.

tobeythorn
—
2010-05-11T00:53:30Z —
#8

.oisyn, In my opinion, message passing is a requirement of encapsulation. If telling a object to do something that it doesn't understand can break a program, then the object isn't completely encapsulated. Furthermore, since c++ doesn't natively support reflection or dynamic typing, the programmer must always be aware of exactly what class each object is, which doesn't seem like pure encapsulation to me either. The point is that c++ really isn't much different from c, just sometimes more convenient.

In c we would write...

Rabbit* myRabbit = rabbit_new();
rabbit_run(myRabbit);

In c++ we would instead write...

Rabbit* myRabbit = new Rabbit();
myRabbit->run()

Are these not exactly the same?

Reedbeta
—
2010-05-11T01:51:23Z —
#9

You could just as well say that writing

|myRabbit|
myRabbit := Rabbit new.
myRabbit run

in Smalltalk is exactly the same as the two examples you posted. Does it really matter whether you call what's going on "message passing" or "calling a method"? It's all the same when you get down to it.

IMHO, the core concept of object orientation is that some data (an object's state) and code (its behaviors) are tightly integrated and presented as a unified component (an object) to the outside world. Languages can support this model to a greater or lesser extent. C++ doesn't fail to be object-oriented just because it doesn't take the idea to some (il)logical extreme.

tobeythorn
—
2010-05-11T02:07:29Z —
#10

Reedbeta, No, I don't think so. In all three example the grammar is essentially identical. However, the underlying behavior of message passing is different, even though it does involve a function call. In contrast, the underlying behavior of both the c and c++ example I gave is the same.

I think that your definition of object-orientation is both fair and de facto. C++ is then clearly an object orientated language. However, I think most people do include encapsulation in their definition.

geon
—
2010-05-11T10:00:27Z —
#11

If telling a object to do something that it doesn't understand can break a program, then the object isn't completely encapsulated.

On the other hand, if your compiler *let* you pass a message the object doesn't understand, it could easily break your program.

I have been working with Objective C the last few weeks, where you call methods in objects and the runtime decides if the method is supported or not for the speciffic object.

I really can't see how it is any better to use lots of void* (which is what Objective C does) instead of base class pointers, where you *know* exactly what methods you can call.

Sol_HSA
—
2010-05-11T10:10:52Z —
#12

C is *still* more portable than C++.

It's possible to understand everything about C. I'm not quite sure if the same can be said about C++. It feels like I keep forgetting more obscure things about C++ than I learn.

C++ has plenty of hidden overheads that also may vary from platform to platform or compiler to compiler.

Since C is older, the compiler optimizations have had more time to mature.

Preferences.

Basing designs on C++ doesn't mean they automatically become easier, clearer, faster to develop for. Just look at Symbian.

Before I moved from C to (majorly) C-With-Classes C++ coding, my code was already turning very much class-like (storing states in structures that were passed along etc). If C++ had not been available to ease my typing, I'm pretty sure I'd continued the same route.

rouncer
—
2010-05-11T10:56:22Z —
#13

Maybe Carmack just hates object oriented, i dont use it either.

phresnel
—
2010-05-11T12:36:27Z —
#14

@Sol_HSA

Since C is older, the compiler optimizations have had more time to mature.

I think that argument is mostly void, and the contrary is the case: Because C++ is mostly compatible to C, a lot of C++ code can benefit from those optimizations. And because C++ offers additional and very powerful tools, it has even more stamina in optimization.

.oisyn, In my opinion, message passing is a requirement of encapsulation. If telling a object to do something that it doesn't understand can break a program, then the object isn't completely encapsulated.

Nonsense. Programming by contract or not has nothing to do with OOP. Also, allowing the compiler to catch errors the runtime would otherwise catch does also have it's advantages.

Furthermore, since c++ doesn't natively support reflection or dynamic typing

C# does, which uses the same method calling paradigm as C++.

the programmer must always be aware of exactly what class each object is, which doesn't seem like pure encapsulation to me either.

Yes it is. Because the programmer doesn't need about the actual implementation of the object. It only needs it's interface. Which has it's advantages, because you know which "messages" it understands and what parameters you can give those messages.

Besides, it would be very easy in C++ to devise objects that actually uses message passing rather than method calling, if you find that more attractive. But that doesn't make it any more OOP.

The point is that c++ really isn't much different from c, just sometimes more convenient.

That's why OOP is a design paradigm, and has nothing to do with syntax. You can design an OOP program in C just fine.

In c we would write...

Rabbit* myRabbit = rabbit_new();
rabbit_run(myRabbit);

In c++ we would instead write...

Rabbit* myRabbit = new Rabbit();
myRabbit->run()

Are these not exactly the same?

As is with any language. What's your point?

vrnunes
—
2010-05-11T15:49:14Z —
#17

But answering again to the original poster =), I still think the only reason was raw performance, because at that time processors were a lot slower than today processors, and Mr. Carmack knew that.

Before that, ASM was the main language of choice for games.

tobeythorn
—
2010-05-11T16:03:24Z —
#18

My point is that I don't see much motivation for migrating from c to c++. In contrast, message passing, whether you like it or not or consider it an import or optional part of OOP actually has functionality beyond a simple function call.

Yes it is. Because the programmer doesn't need about the actual implementation of the object. It only needs it's interface.

In non-message passing environments, if I have an array [snake, elephant, bird] and want to call a function move() on each element of the array, I can't without an unnecessary mess, without explicitly casting (which is just a fancy way of calling an explicitly different method for each), which means that I really do have to know about the guts of the objects, and not just their interfaces. Sorry, but to me that is just not encapsulation.

Mihail121
—
2010-05-11T16:26:45Z —
#19

They could've wrapped the archaic C code in C++, no problem at all. I guess Carmack & Company like C m0ar, just as I do. If I have the choice between C++ and C, I would never pick C++ for anything in the world. Being simple, easy, well-documented and portable C has served me well over the years. For really large projects I would probably pick a MDE-approach with a bytecode language such as C#.

fireside
—
2010-05-11T16:38:59Z —
#20

In non-message passing environments, if I have an array [snake, elephant, bird] and want to call a function move() on each element of the array, I can't without an unnecessary mess, without explicitly casting (which is just a fancy way of calling an explicitly different method for each), which means that I really do have to know about the guts of the objects, and not just their interfaces. Sorry, but to me that is just not encapsulation.

That's just using an abstract. Every OO language does that. You don't recast, you just put all the objects in a base class container and call the abstract function.