gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > gcc vs g++

#15386 - doudou - Wed Jan 21, 2004 8:35 pm

I'm doing a project that is getting pretty big. So far, I used only C code to compile with gcc. For some "clean implantation" issues, I'm now wondering if I should use C++ classes and build with g++. I don't know anything about the g++ compiler and I wonder if it's a good choice to pass from gcc to g++. I'd like to know if I can expect the same performance from both compiler.

#15387 - sajiimori - Wed Jan 21, 2004 8:40 pm

Both are simply front ends to the real compiler (cc1), assembler (as), and linker (ld). They merely set different flags by default. g++ sets things up to be C++-friendly.

Out of curiosity, what kind of issues are making you think about switching to C++? Don't worry -- I'm not going to try to talk you out of it (though I might offer ways to clean things up without switching). =)

#15389 - doudou - Wed Jan 21, 2004 9:20 pm

It's just that i want to use a more object oriented approach. Ex : i now want to introduce monsters in the game and a clean way for this would be to have a pure virtual class monster with a virtual function AI that is implemented in derived classes like Dragon. Is this a good enough reason ?

#15391 - DekuTree64 - Wed Jan 21, 2004 9:41 pm

Yeah, I'm doing a sort of OO battle system for my RPG, where you have things like menus and numbers to show damage all put into a list of 'objects' that need updated each frame. It may work better to use C++, but I kind of like C more anyway, so I just made a basic object struct with a pointer to the next one in the list, and a type and such, and then make sure all the specific things have those same first members, so I can just use a switch statement on the type to decide which update function to call. Or maybe even a table of function pointers so each type value is an index in the table.
Another way I've heard of is to give the base struct some function pointer members and when creating an object, set the pointers to the update function for the current type.
Bottom line: it doesn't matter what language you use as long as you get the job done.

Anyway, I've never tried mixing C and C++, but I don't see why there would be any problems with it as long as you keep all your dealing with classes and other C++-related things in .cpp files. It all gets compiled to ASM anyway.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#15399 - sajiimori - Thu Jan 22, 2004 1:16 am

Quote:

It's just that i want to use a more object oriented approach. Ex : i now want to introduce monsters in the game and a clean way for this would be to have a pure virtual class monster with a virtual function AI that is implemented in derived classes like Dragon. Is this a good enough reason ?

IMO, it's a good sign that you are even thinking about specific reasons to use C++ features, instead of just "because everybody says C++/OO is better".

If you want to start using C++ features in some places, first rename all your .c files to .cpp and compile them with g++.

No, seriously! GCC is less strict when compiling .c files (as it should be), and recompiling your C code as C++ will bring any "relaxed" C-style code to light, such as using fuctions without declaring them.

After that, you can feel confident about using virtuals, overloaded functions, constructors, and other handy C++ features in places where they will make things significantly simpler, without feeling compelled to reshape your entire program to fit it into the OO mold.

Edit: a concrete comparison of the monster AI situation:
Code:

/*
 *  monster.c
 */

struct MonsterType;

typedef struct Monster
{
  struct MonsterType* type;
  int x, y;
} Monster;

typedef struct MonsterType
{
  void (*think)(Monster*);
} MonsterType;

Monster all_monsters[MAX_MONSTERS];
int next_available_monster;

Monster* create_monster(MonsterType* t)
{
  /* naive allocation scheme */
  Monster* m = &all_monsters[next_avaliable_monster++];
  m->type = t;
  return m;
}

void monsters_think()
{
  Monster* m = all_monsters;
  Monster* end = m + MAX_MONSTERS;

  while(m < end)
  {
    m->type->think(m);
    m++;
  }
}

/*
 *  dragon.c
 */

Peasant* dragon_find_peasant(Monster*);
void dragon_eat_peasant(Monster*, Peasant*);

void dragon_think(Monster* m)
{
  Peasant* p;

  p = dragon_find_peasant(m);
  if(p)
    dragon_eat_peasant(m, p);
}

const MonsterType Dragon = { think: dragon_think; };

/*
 *  magic_spells.c
 */

void zap_wand()
{
  Monster* m;
  player_say("Hmm, I wonder what this wand does?");

  m = create_monster(&Dragon);
  m->x = player.x;
  m->y = player.y + 10;

  player_say("Oh crap!");
}

Code:

//
// monster.cpp
//

struct Monster
{
  int x, y;
  virtual void think() = 0;
};

// dummy type to initially fill array
struct BlankMonster
{
  void think() {}
};

BlankMonster all_monsters[MAX_MONSTERS];
int next_available_monster;

Monster* allocate_monster()
{
  // naive allocation scheme
  return &all_monsters[next_avaliable_monster++];
}

void monsters_think()
{
  Monster* m = all_monsters;
  Monster* end = m + MAX_MONSTERS;

  while(m < end)
  {
    m->think();
    m++;
  }
}

//
// dragon.cpp
//

// any additional data members should be static
// for this example, because Dragons have to fit
// in the same array with other Monster types.
struct Dragon : public Monster
{
  void think();
  Peasant* find_peasant();
  void eat_peasant(Peasant*);
};

void Dragon::think()
{
  Peasant* p;

  p = find_peasant();
  if(p)
    eat_peasant(p);
}

//
// magic_spells.cpp
//

void zap_wand()
{
  player_say("Hmm, I wonder what this wand does?");

  // use placement new to put the dragon in
  // the pre-allocated array.  (is this the right
  // syntax?)
  Dragon* m = new (monster_allocate()) Dragon;

  m->x = player.x;
  m->y = player.y + 10;

  player_say("Oh crap!");
}

#15483 - doudou - Fri Jan 23, 2004 1:44 am

I cleaned my code since g++ is more restrictive than gcc (which is ok to me). I now have a problem that i did not have with gcc (and still don't have since i still can build my project using gcc) : stuff declared in a file that is used by many (at least 2 ;-) ) other files are bringing multiple defines error. Maybe my way to build is not good...here is my makefile :


g++ -c -O3 -mthumb -mthumb-interwork engine\gfx.c
g++ -c -O3 -mthumb -mthumb-interwork engine\misc.c
g++ -c -O3 -mthumb -mthumb-interwork engine\sprite.c
g++ -c -O3 -mthumb -mthumb-interwork engine\spriteengine.c
g++ -c -O3 -mthumb -mthumb-interwork engine\saveload.c
g++ -c -O3 -mthumb -mthumb-interwork engine\text.c
g++ -c -O3 -mthumb -mthumb-interwork engine\DMACopy.c
g++ -c -O3 -mthumb -mthumb-interwork engine\anims.c
g++ -c -O3 -mthumb -mthumb-interwork engine\stats.c
g++ -c -O3 -mthumb -mthumb-interwork engine\levels.c
g++ -c -O3 -mthumb -mthumb-interwork engine\AI.c
g++ -c -O3 -mthumb -mthumb-interwork engine\Time.c
g++ -c -O3 -mthumb -mthumb-interwork engine\Debug.c
g++ -c -O3 -mthumb -mthumb-interwork main.c

g++ -mthumb -mthumb-interwork -o mygame.elf mygame.o gfx.o misc.o spriteEngine.o sprite.o saveload.o text.o DMACopy.o anims.o stats.o levels.o AI.o time.o debug.o

objcopy -O binary mygame.elf mygame.gba

#15489 - tepples - Fri Jan 23, 2004 3:27 am

You need to use the keyword extern to reference global variables in your project's header files, and only one source code file should declare a global variable without extern. Two declarations of a global variable without extern result in multiple definitions, which the linker cannot resolve.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#15504 - doudou - Fri Jan 23, 2004 3:49 pm

Thanx, it worked. I still wonder why with gcc I did not have this problem.

#15518 - sajiimori - Fri Jan 23, 2004 9:47 pm

For compatability, the linker flags are probably more relaxed with gcc, automatically merging different occurances of the same symbol. I haven't checked the manual though.

#15711 - MoorCrow - Wed Jan 28, 2004 10:42 am

Where can I get my hands on g++ and can I hook it up with Visual C++.

#15714 - MoorCrow - Wed Jan 28, 2004 11:26 am

Got g++ but still getting the same errors that gcc gave me. I thought that
the errors might have been linked to my using classes, which I presume
to be a C++ feature.

I created a class but I can't use it without getting an error.
undefined reference to 'className::functionName'

How can I get to use classes?

#15718 - poslundc - Wed Jan 28, 2004 2:33 pm

Sounds like you either didn't define all of the class methods you are calling, or you didn't submit all of the .cpp files to g++ when you called it.

Dan.

#15735 - MoorCrow - Wed Jan 28, 2004 7:25 pm

O, I thought that the visual studio helper added files to the compile
automatically. Well, added it manually and I works fine. Thanks for the
help.