Archived

This topic is now archived and is closed to further replies.

metamorphic

C or C++?

Recommended Posts

I am a student at college studying computer studies. Next year im going to be doing a games programming course for 3 years. The point is that the book i have, and almost all the articles on gamedev.net use C not C++. Why dont they use C++? which one should i learn? If i should learn C first, is there any problems learning C++ after? (ive heard people have a hard time changing over some things in C++) Which is easier to program in? Thanks for any help

Share this post


Link to post
Share on other sites
I would also recommend going straight into C++. Programming OO style requires a slightly different mindset, which can be hard to break away from if you get toooo accustomed to programming declarative languages (like C, etc.)

Share this post


Link to post
Share on other sites
OK, this frequent question is pissing me off, learn both, then choose it doesnt matter, a language doesnt make a good game, a programmer does.

Share this post


Link to post
Share on other sites
calling a method in c++ is more expensive that calling a __cdecl function. At the ''very essence'' what''s the diference between:

DrawCircle(int radius, int xpos int ypos)
and
Circle.Draw(int xpos, int ypos)

Share this post


Link to post
Share on other sites
This is for Marius (just incase he meant what I''m afraid he did ). These two are different:
  
void DrawCircle(int radius, int xpos, int ypos) {
/* ... */
}

  
class Circle {
public:
void Draw(int radius, int xpos, int ypos) {
// ...

}
};

This one is the same as the first:
  
class Circle {
public:
static void Draw(int radius, int xpos, int ypos) {
// ...

}
};

This one is the same as the second:
  
void DrawCircle(struct Circle *C, int radius, int xpos, int ypos) {
/* ... */
}

Lesson: if it doesn''t use any member variables or functions, make it static.

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
quote:
Original post by narfidoo
C is better. But it doesn''t matter. I would recommend learning C++ though. Nobody seems to realize that C makes more sense.

This is flamebait. C doesn''t make more sense. It just makes a different kind of sense. It''s procedural programming instead of object-oriented programming: it revolves around the actions rather than around the actors. C++ has several advantages over C, but is harder to learn to use properly. And that''s about it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

C++ has several advantages over C, but is harder to learn to use properly. And that''s about it.



And C++ is slower than C. This doesn''t matter for large scale applications, but it can be an issue in game programming. It also depends on the compiler, but in general C optimizes better than C++, and the code flow is better to control, since it is lower-level than C++.

- AH

Share this post


Link to post
Share on other sites
I'd say you go for C first. It it is ten times simpler than C++ and you are going to need to know C anyway even if you stick with C++ in the end, so you won't lose anything by learning C first.

Also, C is an honest language: it does what you tell it to do. C++ on the other hand has a passion for hiding things away from you. All sorts of things go under the hood: constructors, exceptions, overloaded operators and so forth.


Edited by - Diodor on November 17, 2001 1:11:46 AM

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster

And C++ is slower than C.



It is? In what respect? Are we talking about the extra dereference to look into the vtable? As opposed to the lightning fast way of doing it in C with a switch statement, with which the best a compiler can do is turn it into a lookup table?

Here''s what you do: write your program, in whatever language you like; profile it and then see where it is spending all its time. Pinpoint those areas for optimisation - the first choice being find a better algortihm. Or hand code it in assembly if you''re feeling really anal.

The point is, you can write inefficient code in any language. Or you can write effecient code. It''s swings and round-abouts.

At the very least, if people are going to post ''facts'', it''d be nice to seem some substantial or even circumstantial evidence

How come no-one has stepped in to say "Hey, why don''t you learn Pascal?" After all, it can often produce faster tighter code than C or C++. It lets you get away with much less too, so it''s harder to do unintentional things ( if ( x = 3 ) ... anyone?).

I don''t code in Pascal, by the way



--

MP3 Dancer

Get A Stripper on your desktop

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster

And C++ is slower than C.



Half-Life uses C++, and that is by no means slow. Quake 3 uses C, that also isn''t slow. The speed difference is so negligable that it can be discounted.

Share this post


Link to post
Share on other sites
C++ used to be slower than C - when it first arose. However, over time compiler writers have got smarter. There''s not that much difference between the two now (if any), so it''s not a real factor. As others have said, use assembler if you find a slow point.

Using a procedural language because it''s _slightly_ faster (possibly) is pretty silly. There are *far* too many advantages of object-oriented programming to give it up over small, and possibly imaginary, speed differences.

C makes more sense to some because it''s the way you first get taught programming (usually): i.e. procedurally. When you get onto o.o. things seem so complex, but it''s just a different way of thinking - once you''ve got over the difference, both are straightforward.

I would say this: find out what language you''ll be doing on this games programming course, metamorphic, and learn that. Did you really need to ask the question here?

Also, to taliesin73: Respect! Delphi.

Alistair Keys

"There are two kinds of people, those who finish what they start and so on."
-- Robert Byrne

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
My theory that C++ is slower than C seem to have upset some people here

Unfortunately it (still) is the case. And the speed difference is definitely *not* negligable. I did some programming on the OpenWatcom project (www.openwatcom.org) and I quickly run into the problems, and they are not easy to solve (from the compilers point of view). This is why: the main problem are complex classes, and especially overloaded operators accessing them. But it already starts with simple classes.
Say you define a class ''vector'' with the members x, y and z. Now you have nice operators for this class: +, -, etc... Easy and clean. But slow. For an addition, in plain C you would write C.x=A.x+B.x, and respective for y and z. This straigntly compiles into 3 to 9 ASM opcodes, depending on context and optimization.
Now in C++ you write C=A+B.

Now this is now *highly* dependent on your operator definition style and where *exactly* you did constant dereferencing, but normally this statement invokes several hidden copy constructors, even that for this simple class they are *not* needed. Especially the so called ''return value optimization'' is screwed in most (if not all) compilers, because it is extremly difficult to get working. The ''='' operator invokes (again) a ''hidden'' copy constructor. Lots of people argue that this is the way C++ worked (if I wrote C=, then I specifically asked the compiler to assign the value to a new instance). OK, that''s an argument, but it is slower than C, at the same functionality.

So you end up with alot more ASM opcodes for the *same* function than the one written in plain C. It is not much, and depends on compiler, settings, and even more on the way you defined your classes, operators and the code context, but if you use this in an inner loop (eg. for vertex shaders, lots of vector math is involved per vertex here) then the difference can be enormeous.

Optimization can go really far, but the problem is that some optimizations actually *break* some fundamental C++ principles, so they can not be safely implemented. C code doesn''t have this problem. It''s a tradeoff.

For really high performance games I would go for straight C, it *is* better to optimize, even on the best compiler. For large scale applications (aka. 3Dsmax, MS word, etc...) there is no way around C++. I is just cleaner and all in all more professional.

- AH

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
Say you define a class ''my_vector'' with the members x, y and z. Now you have nice operators for this class: +, -, etc... Easy and clean. But slow. For an addition, in plain C you would write C.x=A.x+B.x, and respective for y and z. This straigntly compiles into 3 to 9 ASM opcodes, depending on context and optimization.
Now in C++ you write C=A+B.

*ahem*

In C you write:
C.x = A.x + B.x;
C.y = A.y + B.y;
C.z = A.z + B.z;

For ease of use, you wrap this up in a function call:
Add(my_vector &A, my_vector &B, my_vector &C) 

Since C can''t intrinsically return aggregate types (but it can return pointers to them) you''ll have to pass the result object as well.

Starting to get messy, eh?

quote:
Now this is now *highly* dependent on your operator definition style and where *exactly* you did constant dereferencing, but normally this statement invokes several hidden copy constructors, even that for this simple class they are *not* needed. Especially the so called ''return value optimization'' is screwed in most (if not all) compilers, because it is extremly difficult to get working. The ''='' operator invokes (again) a ''hidden'' copy constructor. Lots of people argue that this is the way C++ worked (if I wrote C=, then I specifically asked the compiler to assign the value to a new instance). OK, that''s an argument, but it is slower than C, at the same functionality.

Not if you use references (which you''re supposed to):
my_vector &my_vector::operator+ (my_vector &v1, my_vector &v2)
{
vector v;
v.x = v1.x + v2.x;
v.y = v1.y + v2.y;
return v;
}

Is this less efficient than the C version? No. Why, because the overhead of the object dereference for the method is equivalent to the overhead of passing the "object" to a function. You''re not comparing equivalent ideas; if you define a function Add(my_vector &v1, my_vector &v2) in C, the resulting code will be identical total in number of instructions generated.

The C++ code above is then used like so:
C = A + B; 

Even better, we can do this:
Z = A + B + C + D + E + F + ... + Y; 

In C... ooh, nasty!

Even better, we can improve the performance of the addition operator by using templates (there''s an article on it on this site; good stuff). C? No can do.

quote:
So you end up with alot more ASM opcodes for the *same* function than the one written in plain C. It is not much, and depends on compiler, settings, and even more on the way you defined your classes, operators and the code context, but if you use this in an inner loop (eg. for vertex shaders, lots of vector math is involved per vertex here) then the difference can be enormeous.

I think your C++ just sucks, that''s all. We''ve argued over whether C++ results in more ASM instructions or not several times on these boards, and the conclusion is that it doesn''t. C requires the calling function to generate a lot of the entry code while C++ leaves that to the called function. Yes, a C++ method has an additional parameter for the object, but if you are operating on a structure and need to pass it to the function in C then the result is identical.

Poor OpenWatcom. (Couldn''t help myself)

metamorphic: use whatever you feel works closest to the way you think. I''m an almost exclusively C++ programmer (I used C for months only), and I generally dislike "procedural" languages. But sometimes my work has required me to use them (Perl, C...) A good programmer learns that the concepts are portable between languages, and that languages are tools (each of which has scenarios where it is best.)

Good luck.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Oluseyi:

OK

quote:

For ease of use, you wrap this up in a function call:
Add(my_vector &A, my_vector &B, my_vector &C)



C=A+B in C++ is *NOT* equivalent to a C function call. If you do this for your own ease of use, well thats *your* problem. You have to deal with the overhead. But let''s discuss a bit C++ principles. Writing C=A+B simply means ''add object A to B and put the endresult in C'', we do not care about the type. This is *not* the same than calling a convenience function under C. But it *is* the same as the C.x=A.x+B.x etc stuff. The only difference is that in C you have to care about the type yourself.

So we have: C.x=A.x+B.x etc and C=A+B are supposed to do *the same thing*. So I require them to create the *same* ASM code. They don''t. They might be conceptually different, but this is of no importance here.

quote:

Not if you use references (which you''re supposed to):
[snip]
Is this less efficient than the C version? No.



Yes. Did you tried it ? Try both the C and C++ version, and disassemble them.

quote:

Why, because the overhead of the object dereference for the method is equivalent to the overhead of passing the "object" to a function.



Yes, that''s correct. Function overhead might even be higher. BUT: We were *not* talking about calling a C function, see above.

quote:

The C++ code above is then used like so:
C = A + B;
Even better, we can do this:
Z = A + B + C + D + E + F + ... + Y;
In C... ooh, nasty!


Yep, that''s the problem of C, it''s a lot messier. As I said, it''s a tradeoff.
quote:

Yes, a C++ method has an additional parameter for the object, but if you are operating on a structure and need to pass it to the function in C then the result is identical.



Ofcourse C++ has the intrinsic ''this'' parameter, but this is not much of a difference. The problem is in the concept itself. I repeat myself here: C=A+B is the same than C.x=A.x+B.x... but *not* the same as something like AddVect(...) !

quote:

Poor OpenWatcom. (Couldn''t help myself)



It optimizes *ways* better than MSVC. You should perhaps *Try* it before ranting And as I said, I tried the above ASM compares on *several different* compilers (Borland, MSVC, GCC and OpenWatcom). It is just that I actively programmed on the OpenWatcom compiler. Did you ever tried to write a compiler, or parts of it ? PErhaps you should give it a try, might show you some insight...

quote:

I''m an almost exclusively C++ programmer (I used C for months only), and I generally dislike "procedural" languages



Yes, your opinion is very biased. C++ is *not* the successor of C, it''s complementary. An addition for a another type of programming field. But it''s not very good for high performance programming. Including games and operating systems... It''s a cleaner, more abstract language, and I like it a lot myself. But it is not as effective as C. Same thing if you go even lower level: C is alot easier than pure ASM (I think we agree there , but not as effective.

quote:

A good programmer learns that the concepts are portable between languages, and that languages are tools (each of which has scenarios where it is best.)



Fully agree here

- AH

Share this post


Link to post
Share on other sites
Oluseyi hit the nail on the head.

Furthermore, the "classic game OOP problem" of a vector coordinate class with operator overloads for matrix/vector transforms is one of the most classically difficult-to-solve problems confronting computer science right now. Matrix math (vectors are a specialized matrix of course) is incredibly easy to do inefficiently, and incredibly difficult to do correctly. The JOOP has about 4 articles a year about this problem, and the only likeable solution I''ve seen so far is to have matrix operations return proxy objects:
y = a * b + c creates a multiply_proxy for a * b, an add_proxy for (a * b) + c, and then those are finally used in the = operation to calculate y. The math is evaluated all at once, hopefully minimizing intermediate math steps and temporaries.

It is incredibly difficult to create an efficient generalized matrix math library with natural language semantics in C++, and impossible to do in C. In either language, you can hand-code routines to do special operations rather than a general class, and since C++ _is_ C, they''ll compile to the same code, unless you''re inlining and then C++ may beat out C.

I used to get really upset at these "C is faster/better/spiffier than C++" posts, but I''ve realized that people with this narrow point of view just aren''t good at critical thinking and subsequently are probably not as good a programmer as they could be. The only way this affects me is to protect my job security. So I don''t get torqued anymore, but if somebody does make a specific claim that is incorrect, I try to step in and correct it.

Share this post


Link to post
Share on other sites
quote:

Original post by Oluseyi

For ease of use, you wrap this up in a function call:

Add(my_vector &A, my_vector &B, my_vector &C)

Since C can''t intrinsically return aggregate types (but it can return pointers to them) you''ll have to pass the result object as well.

Starting to get messy, eh?



Actually, it''s more like
Add (my_vector *A, my_vector *B, my_vector *C);

And no, it''s not messy, it''s as straight forward as it gets.



quote:

my_vector &my_vector::operator+ (my_vector &v1, my_vector &v2)
{
vector v;
v.x = v1.x + v2.x;
v.y = v1.y + v2.y;
return v;
}



Except that the operator + can only take one parameter and the v vector is destroyed before the operator function quits, so you cannot return v as a reference, you must return it as a value. The funny thing is that a = b + c works well. a = b + c + d doesn''t so ignoring the compiler''s warning can create a nasty hard to track bug.


The correct way to do the + operator is:
my_vector my_vector::operator+ (my_vector &o)
{
my_vector v;
v.x = x + o.x;
v.y = y + o.y;
return v;
}

What happens is that when the operator gets called, v''s constructor gets called, then at the return spot a new vector is created with a copy constructor then v is destroyed. That object will be returned, then it will be also destroyed at some point.

Whatever the C++ compiler makes of all these is beyond me.

So, 2 bugs and a lot of wierd under the hood stuff for C++, a simple function that does the job for C.

C++? Thanks, but no thanks.

Share this post


Link to post
Share on other sites
btw, is there a significant difference between how a C compiler will compile C code and how a C++ compiler will compile C code?

Right now I write procedural code using a C++ compiler but ignoring (much of the time) the ++ features. Does this count as C?

Share this post


Link to post
Share on other sites
quote:
Original post by Stoffel
In either language, you can hand-code routines to do special operations rather than a general class, and since C++ _is_ C, they''ll compile to the same code, unless you''re inlining and then C++ may beat out C.

C has the inline keyword too.

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

It is incredibly difficult to create an efficient generalized matrix math library with natural language semantics in C++,



I agree

quote:

and impossible to do in C.



I do not agree.

quote:

In either language, you can hand-code routines to do special operations rather than a general class, and since C++ _is_ C, they''ll compile to the same code,



Right, but in both cases this will be plain C, without using the extended OOP features. This classifies as pure C and *is* more efficient.

quote:

unless you''re inlining and then C++ may beat out C.



No, it will be the same.

quote:

I used to get really upset at these "C is faster/better/spiffier than C++" posts, but I''ve realized that people with this narrow point of view just aren''t good at critical thinking and subsequently are probably not as good a programmer as they could be. The only way this affects me is to protect my job security. So I don''t get torqued anymore, but if somebody does make a specific claim that is incorrect, I try to step in and correct it.



I use to get really upset at these ''C++ is always better than C'' posts. Don''t you think that *your* point of view is also a little bit narrow-minded ? C != C++. C++ is an extension of C. They are *not* competitors. C++ would not exist without C. And lots of companies choose C, others C++. If C was sooo bad and slow, why is eg. Quake3 done in C ? One can say alot about Carmack, but definitely not that he''s a bad programmer. So why did he choose C ?

The intersting thing about all those people crying ''C is better tah C++'' or the other way round, is that almost none of them actually *tried it*. ''I am using C++ at my company, I''ve always used C++, so it MUST be best'', and the otherway round. This is childish. Just go and try it out, write some equivalent C and C++ code and disassemble the result. You might be surprised.

quote:

btw, is there a significant difference between how a C compiler will compile C code and how a C++ compiler will compile C code?



I don''t think so. At least, it shouldn''t.

quote:

Right now I write procedural code using a C++ compiler but ignoring (much of the time) the ++ features. Does this count as C?



Yes.

- AH

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
and BTW: This thread is fully interchangeable with ''Linux vs. Windows'', ''OpenGL vs. D3D'', ''Christianity vs. Islam'', etc...

A productive result is extremly unlikely.

- AH

Share this post


Link to post
Share on other sites
I agree with AP completely. I look at it this way: If you''re programming in C, you''re programming in C++ and just not using it''s OOP features, unless you''re using a *cough* straight C complier. If you''re programming in C++, you''re using just that: C with a ++ (even though I say it should be ++C). Either way, we''re all making good games anyway.

Share this post


Link to post
Share on other sites