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++ > C++ classes accessing eachother's private data?

#67203 - LOst? - Mon Jan 16, 2006 5:21 am

Okay, I need to program C++ classes for the moment. I want one class for the level, one class for the level meta, and one class for the player.

Now the player needs to know where in the level he is at, and the level needs to access the level meta to draw the level.

If I put all data in private for each classes, I need to do these methods in public:
Code:
int ReturnLevelX () { return x; }


Imagine me doing the heavy calculations like this:
Code:
offset = ReturnLevelX () + ReturnLevelY () * ReturnLevelWidth ();

If you know how C++ compile these in machine code like I know, then you see my problem. (hint = stack usage high! Slow calculations! Stupid!)

I don't like this. I want to access the x variable directly from another class, but I still want it to be private to the rest of the program.

Is there any solution in C++, that still will be considered true OOP?


And no, I won't put everything in Public. Then I will just skip OOP and do regular C.
_________________
Exceptions are fun

#67206 - MrD - Mon Jan 16, 2006 5:43 am

Quote:
I want to access the x variable directly from another class, but I still want it to be private to the rest of the program.


I think the keyword you're looking for is 'friend'.

Code:
class class_one {
  private:
    int field;
  public:
    // ...
  friend class_two;
}

void class_two::stuff(class_one *dave) {
   dave->field++; // modify dave's stuff directly
}

Friend allows another class access to the private and protected members of a class.
_________________
Not active on this forum. For Lemmings DS help see its website.

#67208 - LOst? - Mon Jan 16, 2006 5:49 am

MrD wrote:
Quote:
I want to access the x variable directly from another class, but I still want it to be private to the rest of the program.


I think the keyword you're looking for is 'friend'.

Code:
class class_one {
  private:
    int field;
  public:
    // ...
  friend class_two;
}

void class_two::stuff(class_one *dave) {
   dave->field++; // modify dave's stuff directly
}

Friend allows another class access to the private and protected members of a class.


Thank you! I was already looking into the friend keyword yesterday, but I wanted your advices first. Since a lot of you are C++ experts.
_________________
Exceptions are fun

#67224 - poslundc - Mon Jan 16, 2006 7:30 am

LOst? wrote:
Imagine me doing the heavy calculations like this:
Code:
offset = ReturnLevelX () + ReturnLevelY () * ReturnLevelWidth ();

If you know how C++ compile these in machine code like I know, then you see my problem. (hint = stack usage high! Slow calculations! Stupid!)


I don't think you know how C++ compiles that into machine code how I know.

Methods with their function-bodies declared in the definition of a class are automatically inlined into your code if you use optimization setting -O1 or higher.

Inlined function calls of this nature compile to the same effect of a direct access to the variable, so there's no additional stack usage or speed penalty.

You can also declare a method as inline without putting it into the class definition, but you need to also put the function body into the header file (or in a corresponding .inl file that can be #included at the end of the header file) in order for it to be inlined everywhere. This is one of the few exceptional circumstances where it's okay to put executable code into a header file.

There are a number of ways to set this up, but the way I like the most (for elegance and encapsulation properties) is as follows:

Code:
class CVector2
{
public:
    int GetX() const;
    int GetY() const;
    void SetX(int x);
    void SetY(int y);

private:
    int    m_x;
    int    m_y;
};

inline
int CVector2::GetX() const
{
    return m_x;
}

inline
void CVector2::SetX(int x)
{
    m_x = x;
}

// etc...


If it looks like a lot of bloated, mostly-redundant code, remember that the purpose of encapsulation is to make things simpler and less error-prone for the user of the class, not for the creator of it. Trust me, I know from experience: a few pennies of discipline early on will save you dollars in bugs down the road.

And yes, with even the lowest optimization setting, the inlined accessor methods will be just as efficient as directly accessing the class members.

As for making friend classes... it's not something you should do lightly, and only in certain integrated designs that behoove it. Breaking the encapsulation barrier is tempting, but two disparate systems (such as a level and a player) should have no need for it.

Dan.

#67227 - LOst? - Mon Jan 16, 2006 8:08 am

poslundc wrote:
LOst? wrote:
Imagine me doing the heavy calculations like this:
Code:
offset = ReturnLevelX () + ReturnLevelY () * ReturnLevelWidth ();

If you know how C++ compile these in machine code like I know, then you see my problem. (hint = stack usage high! Slow calculations! Stupid!)


I don't think you know how C++ compiles that into machine code how I know.

Methods with their function-bodies declared in the definition of a class are automatically inlined into your code if you use optimization setting -O1 or higher.

Inlined function calls of this nature compile to the same effect of a direct access to the variable, so there's no additional stack usage or speed penalty.


First, I am using Microsoft Visual C++ 6. I am working with debug releases so that I can debug my code in runtime. Microsoft says inline will be ignored in debug.

By the bebugging disassembly view, I can see how much work is needed to get private members returned from a method. It's by far the worst thing I have ever seen, where pointer are loaded into a register to get the method pointer, call it, initializing the stack, get a pointer to the private data into a register, load the data, ..... keeps going like this just to access a little number.


Well, to the problem I got with friend...


And I have tried the friend keyword:
Code:

class A
{
private:
 int x
};

class B
{
public:
friend void Set_X_In_Class_A (A* class_a);
};

void B::Set_X_In_Class_A (A* class_a)
{
 class_a->x = 1;
}


This gives errors:
error C2039: 'Set_X_In_Class_A' : is not a member of 'B'
error C2248: 'x' : cannot access private member declared in class 'A'

_________________
Exceptions are fun

#67228 - LOst? - Mon Jan 16, 2006 8:17 am

LOst? wrote:
poslundc wrote:
LOst? wrote:
Imagine me doing the heavy calculations like this:
Code:
offset = ReturnLevelX () + ReturnLevelY () * ReturnLevelWidth ();

If you know how C++ compile these in machine code like I know, then you see my problem. (hint = stack usage high! Slow calculations! Stupid!)


I don't think you know how C++ compiles that into machine code how I know.

Methods with their function-bodies declared in the definition of a class are automatically inlined into your code if you use optimization setting -O1 or higher.

Inlined function calls of this nature compile to the same effect of a direct access to the variable, so there's no additional stack usage or speed penalty.


EDIT: This will sound so negative. I am just in a bad mood because I have errors to fix. You are progably right.
First, I am using Microsoft Visual C++ 6. I am working with debug releases so that I can debug my code in runtime. Microsoft says inline will be ignored in debug.

By the bebugging disassembly view, I can see how much work is needed to get private members returned from a method. It's by far the worst thing I have ever seen, where pointer are loaded into a register to get the method pointer, call it, initializing the stack, get a pointer to the private data into a register, load the data, ..... keeps going like this just to access a little number.


Well, to the problem I got with friend...


And I have tried the friend keyword:
Code:

class A
{
private:
 int x
};

class B
{
public:
friend void Set_X_In_Class_A (A* class_a);
};

void B::Set_X_In_Class_A (A* class_a)
{
 class_a->x = 1;
}


This gives errors:
error C2039: 'Set_X_In_Class_A' : is not a member of 'B'
error C2248: 'x' : cannot access private member declared in class 'A'

_________________
Exceptions are fun

#67244 - YopYop - Mon Jan 16, 2006 1:24 pm

Friend key word means that the friend class can access the private member of the "first" class.
it will be more clear with a example :
Code:

class A
{
private:
 int x
friend class B;
};

class B
{
public:
void Set_X_In_Class_A (A* class_a);
};

void B::Set_X_In_Class_A (A* class_a)
{
 class_a->x = 1;
}


edit : juste seen MrD has already said it sorry.

#67254 - LOst? - Mon Jan 16, 2006 2:32 pm

YopYop wrote:
Friend key word means that the friend class can access the private member of the "first" class.
it will be more clear with a example :
Code:

class A
{
private:
 int x
friend class B;
};

class B
{
public:
void Set_X_In_Class_A (A* class_a);
};

void B::Set_X_In_Class_A (A* class_a)
{
 class_a->x = 1;
}


edit : juste seen MrD has already said it sorry.


Thanks.
_________________
Exceptions are fun

#67275 - Mucca - Mon Jan 16, 2006 5:49 pm

Im with poslundc here. Regardless of what the debugger is showing you, inline accessor methods ( always const for Get methods ) are in no way slower than accessing members directly, and a whole lot safer and more flexible, especially when you start filling out your code with asserts and error checking etc. Debug config only ignores inlining for your convenience when debugging (duh), and under a release config everything is dandy.

Friend is a strange beast, for me it breaks to many rules and is awkward to use. For base classes that someone else will extend, its nigh-on useless, as it does not survive inheritance, and jeopradises virtual behaviour.

#67276 - poslundc - Mon Jan 16, 2006 5:51 pm

LOst? wrote:
First, I am using Microsoft Visual C++ 6. I am working with debug releases so that I can debug my code in runtime. Microsoft says inline will be ignored in debug.

By the bebugging disassembly view, I can see how much work is needed to get private members returned from a method. It's by far the worst thing I have ever seen, where pointer are loaded into a register to get the method pointer, call it, initializing the stack, get a pointer to the private data into a register, load the data, ..... keeps going like this just to access a little number.


OK, two things:

1. Yes, it means the program is doing an awful lot of extra work... so you can debug it more effectively. That's why you have a debug build, and that's why you use accessor methods in the first place: to prevent errors and make errors easier to track down. It doesn't matter if it runs slowly; that's why you make a release build once you've done the necessary debugging.

2. While I'm not a Windows programming expert I'm certain that there are different optimization levels available to you, and that you will still be able to debug in most of them. This is what's called an "optimized debug" build. At the very least, I'm sure you can turn on function inlining (you can in GCC) specifically if you notice it's slowing down your program execution too much.

I lied; there's a third:

3. I hope you mean you're using MSVC6 for Windows programming, and realize that if you're just using it as a development environment for GBA or DS programming that it doesn't matter what Microsoft tells you, because you're just invoking a different compiler anyway.

I warn you for the final time: don't use friend as an alternative to proper encapsulation. That's NOT following the OOP paradigm, and it will come back to bite you in the ass down the road.

Dan.

#67293 - sajiimori - Mon Jan 16, 2006 7:31 pm

Lost,

If you think a + b * c is "heavy calculations," you're in for a shock.

If you think inline functions are "stupid," you're in for another shock.

If you're judging the efficiency of your program by how well it runs in debug mode, your results will not be meaningful.

If you started this thread not being aware of inlined functions and the 'friend' keyword, it's unwise to argue with professional programmers.

If you're optimizing before you've encountered an actual speed problem in a release build, you're putting the cart before the horse.

#67322 - Ultima2876 - Tue Jan 17, 2006 12:31 am

Putting the cart before the horse can be good, if you've got someone trying to kill your horse ;P

#67343 - LOst? - Tue Jan 17, 2006 6:20 am

sajiimori, you are one of the best C/C++ programmers here. I have gotten a lot of advices from you. Your reply was very offensive. You are protecting C++, or you want to get to me for my C++ accusations when i am clearly not a full grown C++ programmer yet. I would really like to see your side of this story. What I truly want is to be able to program games, programs, in pure C++ OOP. All my current projects in C++ have been very demanding, and the final result didn't work because the target computers couldn't operate in full speed. I had to spend months rewrite my programs in C just to make them run as I wanted them to.
Just because I have a computer with 4 Intel Xeon CPUs operating at 2.2 GHz doesn't mean my program must run on it. Going down to Celeron 800 MHz and my program is dead! What is C++ for? It's a hard question that I try to answer myself over and over. Maybe I must wait 10 years until everyone has 8 GHz computers before I can do games for them.
I must say that I wrote my game directly in assembler, and it worked with 60fps on my Pentium II 233 computer. So it is not how I make the game that makes it slow. it is how C++ is constructed that makes it slow.

sajiimori wrote:
Lost,

If you think a + b * c is "heavy calculations," you're in for a shock.

If you think inline functions are "stupid," you're in for another shock.

If you're judging the efficiency of your program by how well it runs in debug mode, your results will not be meaningful.

If you started this thread not being aware of inlined functions and the 'friend' keyword, it's unwise to argue with professional programmers.

If you're optimizing before you've encountered an actual speed problem in a release build, you're putting the cart before the horse.


a + b * c is not heavy. But "call a function, initialize stack, get pointer, get value, return value, clean up function" + "call a function, initialize stack, get pointer, get value, return value, clean up function" * "call a function, initialize stack, get pointer, get value, return value, clean up function" is heavy considiring you just want a little number. If you want proof, look below.

Inline functions are stupid when they are not working as they should.

I am comparing to C. If I write the same functions in C using structures, the speed will be much faster, even in debug releases.

It's unwise to be unprepared when arguing with professional programmers. I am not unprepared. I come with proof. Sure i didn't know how friend keyword worked, but I knew it existed. I came here for advice, and I am getting it.

Optimizing for me is writing everything in C, or make everything public in C++, because the speed matters!

It is time for me to show you the truth. You are welcome to judge this disassembly output, even make your own in ARM assembly with GCC just to prove me wrong. Here I go:

Dissasembly of very simple code in C:
Code:

1:    extern "C"
2:    {
3:        typedef struct
4:        {
5:            int x;
6:            int y;
7:            int z;
8:        } POSITION;
9:
10:       int main (void)
11:       {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,50h
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-50h]
0040101C   mov         ecx,14h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
12:           int offset;
13:           POSITION pos = {10, 20, 30};
00401028   mov         dword ptr [ebp-10h],0Ah
0040102F   mov         dword ptr [ebp-0Ch],14h
00401036   mov         dword ptr [ebp-8],1Eh
14:
15:           offset = pos.x * pos.y * pos.z;
0040103D   mov         eax,dword ptr [ebp-10h]
00401040   imul        eax,dword ptr [ebp-0Ch]
00401044   imul        eax,dword ptr [ebp-8]
00401048   mov         dword ptr [ebp-4],eax
16:
17:           return 0;
0040104B   xor         eax,eax
18:       }
0040104D   pop         edi
0040104E   pop         esi
0040104F   pop         ebx
00401050   mov         esp,ebp
00401052   pop         ebp
00401053   ret


Disassembly of the same code but using C++ and OOP:
Code:

32:
33:   int main (void)
34:   {
004010A0   push        ebp
004010A1   mov         ebp,esp
004010A3   sub         esp,50h
004010A6   push        ebx
004010A7   push        esi
004010A8   push        edi
004010A9   lea         edi,[ebp-50h]
004010AC   mov         ecx,14h
004010B1   mov         eax,0CCCCCCCCh
004010B6   rep stos    dword ptr [edi]
35:       int offset;
36:       POSITION pos;
004010B8   lea         ecx,[ebp-10h]
004010BB   call        @ILT+20(POSITION::POSITION) (00401019)

======SLOW WORLD OF C++=======
00401019   jmp         POSITION::POSITION (00401040)

26:   POSITION::POSITION ()
27:   :   x (10),
28:       y (20),
29:       z (30)
30:   {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,44h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
00401049   push        ecx
0040104A   lea         edi,[ebp-44h]
0040104D   mov         ecx,11h
00401052   mov         eax,0CCCCCCCCh
00401057   rep stos    dword ptr [edi]
00401059   pop         ecx
0040105A   mov         dword ptr [ebp-4],ecx
0040105D   mov         eax,dword ptr [ebp-4]
00401060   mov         dword ptr [eax],0Ah
00401066   mov         ecx,dword ptr [ebp-4]
00401069   mov         dword ptr [ecx+4],14h
00401070   mov         edx,dword ptr [ebp-4]
00401073   mov         dword ptr [edx+8],1Eh
31:   }
0040107A   mov         eax,dword ptr [ebp-4]
0040107D   pop         edi
0040107E   pop         esi
0040107F   pop         ebx
00401080   mov         esp,ebp
00401082   pop         ebp
00401083   ret
==============================

37:
38:       offset = pos.ReturnX () * pos.ReturnY () * pos.ReturnZ ();
004010C0   lea         ecx,[ebp-10h]
004010C3   call        @ILT+10(POSITION::ReturnX) (0040100f)

======SLOW WORLD OF C++=======
0040100F   jmp         POSITION::ReturnX (00401110)

1:    class POSITION
2:    {
3:        int x;
4:        int y;
5:        int z;
6:
7:    public:
8:        POSITION ();
9:
10:       int ReturnX ()
11:       {
00401110   push        ebp
00401111   mov         ebp,esp
00401113   sub         esp,44h
00401116   push        ebx
00401117   push        esi
00401118   push        edi
00401119   push        ecx
0040111A   lea         edi,[ebp-44h]
0040111D   mov         ecx,11h
00401122   mov         eax,0CCCCCCCCh
00401127   rep stos    dword ptr [edi]
00401129   pop         ecx
0040112A   mov         dword ptr [ebp-4],ecx
12:           return x;
0040112D   mov         eax,dword ptr [ebp-4]
00401130   mov         eax,dword ptr [eax]
13:       }
00401132   pop         edi
00401133   pop         esi
00401134   pop         ebx
00401135   mov         esp,ebp
00401137   pop         ebp
00401138   ret
==============================

004010C8   mov         esi,eax
004010CA   lea         ecx,[ebp-10h]
004010CD   call        @ILT+5(POSITION::ReturnY) (0040100a)

======SLOW WORLD OF C++=======
0040100A   jmp         POSITION::ReturnY (00401150)

14:
15:       int ReturnY ()
16:       {
00401150   push        ebp
00401151   mov         ebp,esp
00401153   sub         esp,44h
00401156   push        ebx
00401157   push        esi
00401158   push        edi
00401159   push        ecx
0040115A   lea         edi,[ebp-44h]
0040115D   mov         ecx,11h
00401162   mov         eax,0CCCCCCCCh
00401167   rep stos    dword ptr [edi]
00401169   pop         ecx
0040116A   mov         dword ptr [ebp-4],ecx
17:           return y;
0040116D   mov         eax,dword ptr [ebp-4]
00401170   mov         eax,dword ptr [eax+4]
18:       }
00401173   pop         edi
00401174   pop         esi
00401175   pop         ebx
00401176   mov         esp,ebp
00401178   pop         ebp
00401179   ret
==============================

004010D2   imul        esi,eax
004010D5   lea         ecx,[ebp-10h]
004010D8   call        @ILT+0(POSITION::ReturnZ) (00401005)

======SLOW WORLD OF C++=======
00401005   jmp         POSITION::ReturnZ (00401190)

19:
20:       int ReturnZ ()
21:       {
00401190   push        ebp
00401191   mov         ebp,esp
00401193   sub         esp,44h
00401196   push        ebx
00401197   push        esi
00401198   push        edi
00401199   push        ecx
0040119A   lea         edi,[ebp-44h]
0040119D   mov         ecx,11h
004011A2   mov         eax,0CCCCCCCCh
004011A7   rep stos    dword ptr [edi]
004011A9   pop         ecx
004011AA   mov         dword ptr [ebp-4],ecx
22:           return z;
004011AD   mov         eax,dword ptr [ebp-4]
004011B0   mov         eax,dword ptr [eax+8]
23:       }
004011B3   pop         edi
004011B4   pop         esi
004011B5   pop         ebx
004011B6   mov         esp,ebp
004011B8   pop         ebp
004011B9   ret
==============================

004010DD   imul        esi,eax
004010E0   mov         dword ptr [ebp-4],esi
39:
40:       return 0;
004010E3   xor         eax,eax
41:   }
004010E5   pop         edi
004010E6   pop         esi
004010E7   pop         ebx
004010E8   add         esp,50h
004010EB   cmp         ebp,esp
004010ED   call        __chkesp (004011d0)
004010F2   mov         esp,ebp
004010F4   pop         ebp
004010F5   ret


It looks like C wins. Remember that C++ is just the compiler. As soon you have an executable file, no OOP rules exist. Still the final code is acting like private data is private. The CPU doesn't care, and I don't care. I want speed. I don't want stack functions calls for every calculations I want to make. I still want OOP though, but not this slow!
_________________
Exceptions are fun

#67348 - poslundc - Tue Jan 17, 2006 7:19 am

Lost, I recommend you stick with C rather than trying to use C++. Your entire post was totally ignorant of everything I just said in my previous post. If you cannot wrap your head around those basic concepts, then trying to write code in C++ will only serve to needlessly complicate things.

Quote:
Optimizing for me is writing everything in C, or make everything public in C++, because the speed matters!


Frankly, someone who wrote C++ code using your philosophy would be fired from most companies I've worked at for incompetence.

Dan.

#67350 - LOst? - Tue Jan 17, 2006 8:10 am

poslundc wrote:
Lost, I recommend you stick with C rather than trying to use C++. Your entire post was totally ignorant of everything I just said in my previous post. If you cannot wrap your head around those basic concepts, then trying to write code in C++ will only serve to needlessly complicate things.

Quote:
Optimizing for me is writing everything in C, or make everything public in C++, because the speed matters!


Frankly, someone who wrote C++ code using your philosophy would be fired from most companies I've worked at for incompetence.

Dan.


I don't want to be fired from companies. I don't want to stick to C when C++ is what companies want. If the company want slow code, but easier to debug or find problems in the future, then I will go for that direction.

What you say has yet not been proved to me. Your post is what I dream C++ would be like. That's why I don't want to give up on it. I didn't ignore it. I still program my game in C++, and maybe a miracle will make it fast and optimized in the future.

My current project involves drawing 240 scanlines in 60 fps in Windows. Each time I need to draw a new scanline, private data must be accessed. This goes smooth on computers faster than 1200 MHz. I feel terrible that people with less that speed can't play my game just because I choosed to write the code in C++. It is easy for you to say code is fast when you get the graphics management for free? I mean the GBA or other consoles have GPUs and hardware accelerated graphics. Then just a smal portion of the work is made with C++.

I wanted to mix assembler with C++, but I can't reach the data in classes from assembler. If it was possible, I would be able to speed up the game for sure.
_________________
Exceptions are fun

#67356 - gauauu - Tue Jan 17, 2006 9:20 am

Quote:
What you say has yet not been proved to me.


1. Do some simple experiments with turning debug mode OFF and optimizations ON and compare the disassemblies. Then, and only then, can the discussion of "proving" continue.

2. If you really need a speed up, do some profiling and figure out what part is slowing you down the most. Optimize that. It's probably not going to be simple get accessor functions.

#67381 - kusma - Tue Jan 17, 2006 6:07 pm

LOst? wrote:

My current project involves drawing 240 scanlines in 60 fps in Windows. Each time I need to draw a new scanline, private data must be accessed. This goes smooth on computers faster than 1200 MHz. I feel terrible that people with less that speed can't play my game just because I choosed to write the code in C++. It is easy for you to say code is fast when you get the graphics management for free? I mean the GBA or other consoles have GPUs and hardware accelerated graphics. Then just a smal portion of the work is made with C++.


you are on acid, aren't you?

here's some advice: don't claims about things you don't fully understand.

#67383 - sajiimori - Tue Jan 17, 2006 6:11 pm

Lost,

If you are interested in learning, your pride does you no favors.

If what you "know" is in contradiction to multiple professional C++ programmers who have shipped products, it may be time to forget what you know.

I don't care to prove anything to you. Listen or don't.

#67390 - kusma - Tue Jan 17, 2006 6:36 pm

LOst? wrote:

Dissasembly of very simple code in C:
Code:

1:    extern "C"
[...]
004010F5   ret


It looks like C wins. Remember that C++ is just the compiler. As soon you have an executable file, no OOP rules exist. Still the final code is acting like private data is private.


now, just to show you that you are dead wrong, i wrote some code and dumped the assembly. the code is compiled using gcc 3.3.5, using the -O3-flag.

the c-code was this:
Code:

#include <stdio.h>

struct some_struct
{
   int some_member;
};

void print_some_member_squared(const struct some_struct *ss)
{
   printf("%d\n", ss->some_member * ss->some_member);
}


the c++-code was the following:
Code:

class SomeClass
{
public:
   SomeClass(int x) : some_member(x) {}
   
   int get_some_member() const
   {
      return some_member;
   }
   
private:
   int some_member;
};

void print_some_member_squared(const SomeClass &sc)
{
   printf("%d\n", sc.get_some_member() * sc.get_some_member());
}



now here's the relevant parts of the generated assembly from the c-code:
Code:

print_some_member_squared:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        movl    8(%ebp), %ecx
        movl    (%ecx), %edx
        movl    $.LC0, (%esp)
        imull   %edx, %edx
        movl    %edx, 4(%esp)
        call    printf
        movl    %ebp, %esp
        popl    %ebp
        ret


and here's the relevant parts of the generated assembly from the c++-code:
Code:

_Z25print_some_member_squaredPK11some_struct:
.LFB15:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $8, %esp
.LCFI2:
        movl    8(%ebp), %ecx
        movl    (%ecx), %edx
        movl    $.LC0, (%esp)
        imull   %edx, %edx
        movl    %edx, 4(%esp)
        call    printf
        movl    %ebp, %esp
        popl    %ebp
        ret


note how the generated assembly is IDENTICAL, with the exception of some additional (unreferenced) labels in the c++-code.

#67392 - poslundc - Tue Jan 17, 2006 7:10 pm

LOst? wrote:
I don't want to be fired from companies. I don't want to stick to C when C++ is what companies want. If the company want slow code, but easier to debug or find problems in the future, then I will go for that direction.


I said you would be fired for incompetence, not for not doing what the company wants.

Quote:
What you say has yet not been proved to me.


It's not my job to prove it to you. I already know it works.

Quote:
Your post is what I dream C++ would be like.


Then quit dreaming, wake up and turn on function inlining.

Better still, don't waste your time trying to optimize a DEBUG build. That's not what DEBUG builds are for. They are for DEBUGGING. If you treat your DEBUG build as a RELEASE build, then you are an IDIOT.

Quote:
My current project involves drawing 240 scanlines in 60 fps in Windows. Each time I need to draw a new scanline, private data must be accessed. This goes smooth on computers faster than 1200 MHz. I feel terrible that people with less that speed can't play my game just because I choosed to write the code in C++. It is easy for you to say code is fast when you get the graphics management for free? I mean the GBA or other consoles have GPUs and hardware accelerated graphics. Then just a smal portion of the work is made with C++.


The Pareto Principle applies to software design. In almost any software program, 80% of the processor's time is being spent in only 20% of the code.

If you are optimizing anything other than that 20%, you are wasting your time.

Do what gauauu says and profile your code.

I cannot make things any clearer or plainer than I have just now. If you still don't get it... then you are simply beyond help.

Dan.

#67397 - Ultima2876 - Tue Jan 17, 2006 7:56 pm

Uhm, LOst, don't take it from SWS2B and bring it here... You wanna be careful, these guys aren't so blind =P

#67447 - LOst? - Wed Jan 18, 2006 5:21 am

kusma, thank you for showing me the disassemblies of how real C and C++ code will be compiled into assembler. It's exactly how I want it to be.

poslundc, I need to appologise for ignoring you knowledge. I will trust you from now on. Yes, treating debug builds as release builds are stupid, even if I haven't seen any real speedups when using release builds. You say I need to optimize the release build, and so I will. I will also keep in mind about 20% code / 80% processor time.

sajiimori, as you say, the problem is not C++. The problem is me and how I use it. I am self learned, but most of the big C++ issues come from a book I have had for a while. It is old (does #include <iostream.h> instead of #include <iostream>). It is really bad written. It confuses me more than helps. I need a new book that really help me understand C++ and all the libraries (such as vector and queues) it comes with.


Well thank you all for sharing me your thoughts and helping me design better code.
_________________
Exceptions are fun

#67475 - keldon - Wed Jan 18, 2006 10:12 am

Check for lecture notes for Algorithms and Data structures / Discrete structures (maths). Check google scholar, which searches through university notes. There are still many useful universities with notes available to the public. Google scholar is the new free open university ^_^

#67496 - sajiimori - Wed Jan 18, 2006 5:20 pm

"Thinking in C++" is a great pair of books that illustrate not only the usage of each language feature, but also the reason for the existence of that feature. The second volume covers the standard library.