Jump to content


Wondering why ID choosed C for Quake 3 instead of C++


30 replies to this topic

#1 jokoon

    New Member

  • Members
  • Pip
  • 7 posts

Posted 10 May 2010 - 04:27 PM

Hello ! :)

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 :)

#2 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 10 May 2010 - 04:42 PM

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.
"Stupid bug! You go squish now!!" - Homer Simpson

#3 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1616 posts

Posted 10 May 2010 - 04:48 PM

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.
Currently using Blender and Unity.

#4 imerso

    Senior Member

  • Members
  • PipPipPipPip
  • 433 posts
  • LocationBrasil

Posted 10 May 2010 - 05:55 PM

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

#5 martinsm

    Member

  • Members
  • PipPip
  • 88 posts

Posted 10 May 2010 - 06:42 PM

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++.

#6 tobeythorn

    Valued Member

  • Members
  • PipPipPip
  • 189 posts

Posted 10 May 2010 - 06:45 PM

In addition, some reasons might be:
1. c may have been more portable than c++ at some point

2. without message passing, c++ isn't really objected oriented anyway, and one can write fairly object oriented style code in c.

#7 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 10 May 2010 - 11:27 PM

martinsm said:

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 said:

2. 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.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#8 tobeythorn

    Valued Member

  • Members
  • PipPipPip
  • 189 posts

Posted 11 May 2010 - 12:53 AM

.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?

#9 Reedbeta

    DevMaster Staff

  • Administrators
  • 5340 posts
  • LocationSanta Clara, CA

Posted 11 May 2010 - 01:51 AM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#10 tobeythorn

    Valued Member

  • Members
  • PipPipPip
  • 189 posts

Posted 11 May 2010 - 02:07 AM

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.

#11 geon

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 11 May 2010 - 10:00 AM

"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.

#12 Sol_HSA

    Senior Member

  • Members
  • PipPipPipPip
  • 517 posts
  • LocationNowhere whenever

Posted 11 May 2010 - 10:10 AM

1. C is *still* more portable than C++.
2. 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.
3. C++ has plenty of hidden overheads that also may vary from platform to platform or compiler to compiler.
4. Since C is older, the compiler optimizations have had more time to mature.
5. Preferences.
6. 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.
http://iki.fi/sol - my schtuphh

#13 rouncer

    Senior Member

  • Members
  • PipPipPipPip
  • 2758 posts

Posted 11 May 2010 - 10:56 AM

Maybe Carmack just hates object oriented, i dont use it either. ;)
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#14 phresnel

    Member

  • Members
  • PipPip
  • 47 posts

Posted 11 May 2010 - 12:36 PM

Sol_HSA said:

4. 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.

~/www/ | picogen.org | metatrace
- --- / .-.. . - / -- -.-- / ... .. --. -. .- - ..- .-. . / .- .--. .--. . .- .-. / --. . . -.- -.--


#15 geon

    Senior Member

  • Members
  • PipPipPipPip
  • 939 posts

Posted 11 May 2010 - 03:09 PM

rouncer said:

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

Actually, according to Carmack himslf the Quake I/II/III engines are supposedly written in an object oriented "style".

I'm not really sure what that means.

#16 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 11 May 2010 - 03:42 PM

tobeythorn said:

.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.

Quote

Furthermore, since c++ doesn't natively support reflection or dynamic typing
C# does, which uses the same method calling paradigm as C++.

Quote

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.

Quote

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.

Quote

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?
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#17 imerso

    Senior Member

  • Members
  • PipPipPipPip
  • 433 posts
  • LocationBrasil

Posted 11 May 2010 - 03:49 PM

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.

#18 tobeythorn

    Valued Member

  • Members
  • PipPipPip
  • 189 posts

Posted 11 May 2010 - 04:03 PM

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.

Quote

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.

#19 Mihail121

    Senior Member

  • Members
  • PipPipPipPip
  • 1059 posts

Posted 11 May 2010 - 04:26 PM

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#.

#20 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1616 posts

Posted 11 May 2010 - 04:38 PM

Quote

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.
Currently using Blender and Unity.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users