As a professional game developer myself, I can answer with some authority on this. C++ is the standard in games development because every commercial and the vast majority of free libraries out there for games are written with C or C++ in mind. A lot of game development grew out of the hacker scene, and in that scene they mostly used C because it was a high level language that still allowed the programmer easy access to the low level metal of the PC.
A lot of the stuff we do in game coding involves pointer manipulation, and as a long time Pascal and C programmer, I have to say that pointers are a whole lot easier to use in C.
C++ offers templates. Pascal does not have anything to rival templates yet. C++ offers full support of operator overloading, which only just now FPC supports in a limited manner and Delphi is gaining even more limited support for operator overloading.
Object Pascal may support classes, but the fact that every class inherits from TObject is one major drawback due to two things: every class instance incurs the cost of a pointer to the VMT because at least one method in TObject is declared virtual, and every class must be allocated individually. In C++, a class instance can be declared locally on the stack. Can't do that in Object Pascal. In C++, a class only incurs the cost of a VMT pointer if a method is declared virtual. Therefore
Code:
class TSimple
{
public:
int member;
};
only costs four bytes. In Object Pascal
Code:
type
TSimple = class
public
member: Integer;
end;
is eight bytes in size. Plus you must allocate each class instance by calling Create, which calls several methods of TObject internally. Creating an instance of the same class for use within a function in C++ takes nothing more than just declaring a variable of type TSimple, which takes no more CPU time than it takes to decrement the stack pointer by four bytes.
Say you want a function to create a given sized array of TSimple instances and initialise each array element to 1. The code for this in C would be
Code:
TSimple *AllocArray(int size)
{
TSimple *pArray = (TSimple *)malloc(size * sizeof(TSimple));
memset(pArray, 1, size * sizeof(TSimple));
}
One memory allocation. One call to memset. Simple. Quick. Blindingly fast. Now for the equivalent in Object Pascal.
Code:
type
PSimple = ^TSimple;
PSimpleArray: array [0..High(Integer) div SizeOf(TSimple)] of PSimple;
function AllocArray(size: Integer): PSimpleArray;
var
pArray: PSimpleArray;
i: Integer;
begin
GetMem(pArray, size * SizeOf(PSimple));
for i := 0 to size - 1 do
begin
pArray[i] := TSimple.Create;
pArray[i].member := 1;
end;
end;
That was a lot more complex. We first have to declare a new type that is a pointer to the type we want. Then we have to declare an array of the largest possible size of that pointer type to handle the unknown array size. Allocate an array of pointers to the class instances, then allocate and initialise each class instance individually. Each call to Create calls other methods of TObject, which all takes time per instance. TObject even uses dynamic strings, which on a console system are a big no-no. You allocate once and never reallocate. Unfortunately, dynamic strings reallocate memory almost every time you so much as sneeze at them.
I'll leave the cleaning up of the array to the reader. Hint: The C version is one statement.
Another benefit for C++ is the huge support of tools such as development tools and debuggers. The debugger in Delphi, even in the latest version, is woeful and horribly inadequate when compared to the debugging tools we have access to with C++.
This post may seem like it is bagging Pascal as a game development language. The intent was to point out some reasons why C and C++ is the preferred language in game development, and some of the reasons why. Pascal is a great language. Every language has its strong points and its bad points. In the world of professional game development, C and C++ have more benefits and a lot more support than Object Pascal could provide.
P.S. Bioware used to use C++ Builder for their tools. After Neverwinter Nights, they are looking for alternatives (still using C++). Quotes from http://www.gamasutra.com/gdc2003/fea...kington_03.htm
Last, but not least, we had problems with the toolset component of the project. The Aurora Toolset was built in Borland C++ Builder, based on the fact that we heard all sorts of rumors of a Linux and Macintosh version of Builder. However, this turned into a monstrous headache for development. C++ Builder would throw floating-point exceptions during the middle of the graphics engine, which would not show in the middle of the same library run through Visual C. We couldn't link the graphics library with Builder without going to a DLL, so we had to make the graphics library source tree work on C++ Builder as well. The Macintosh version of Builder vanished into the land of vaporware, and we were left holding the bag.
So, we are trying to duplicate the rules code in both C++ Builder and Visual C for the most important components. We are investigating alternatives to C++ Builder for future projects.
Even trying to maintain C++ code that compiles on both Visual C++ and C++ Builder is a major PITA. Believe me, I've been there and done that. Almost like trying to maintain code that compiles in Delphi and Free Pascal. That is a growing rift right there.
Hint: If they had masked floating point exceptions, they would not have had those errors. This is a pity though that the Visual C++ runtime masks floating point exceptions by default and Borland's runtime does not. Direct3D and OpenGL throw floating point exceptions all over the place.
Bookmarks