Jump to content

  • Log In with Google      Sign In   
  • Create Account


c++ class vs struct+functions


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
15 replies to this topic

#1 jeff8j   Members   -  Reputation: 710

Like
0Likes
Like

Posted 17 May 2014 - 08:38 PM

Im writing a class with a little over 2000 functions associated with it they are pretty small but for this question im asking more in general rather than my use current use case.

 

Would a class having lots of functions in it occur more overhead than a struct+functions that do work on that struct? 


Firefox youtube video and audio downloader MP3 MP4 OGG WEBM

https://addons.mozilla.org/en-US/firefox/addon/simple-youtube-converter/


Sponsor:

#2 SiCrane   Moderators   -  Reputation: 9495

Like
10Likes
Like

Posted 17 May 2014 - 08:52 PM

Assuming the member functions are non-virtual they'll compile into essentially identical machine code as functions that accept structs as pointer or reference arguments.



#3 jeff8j   Members   -  Reputation: 710

Like
0Likes
Like

Posted 17 May 2014 - 08:53 PM

Thanks thats exactly what I was wondering!


Firefox youtube video and audio downloader MP3 MP4 OGG WEBM

https://addons.mozilla.org/en-US/firefox/addon/simple-youtube-converter/


#4 Aardvajk   Crossbones+   -  Reputation: 5843

Like
14Likes
Like

Posted 18 May 2014 - 12:00 AM

Now that the problem is solved, can I ask what on earth design has led you to have a class with 2000 methods?



#5 TorbenC   Members   -  Reputation: 202

Like
1Likes
Like

Posted 18 May 2014 - 02:07 AM

I'm quite interested in this 2k function class too...



#6 swiftcoder   Senior Moderators   -  Reputation: 9759

Like
2Likes
Like

Posted 18 May 2014 - 08:15 AM

http://en.wikipedia.org/wiki/Single_responsibility_principle


Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#7 jeff8j   Members   -  Reputation: 710

Like
0Likes
Like

Posted 18 May 2014 - 10:53 AM

lol well I know it probably not the right way of doing this but im making a x86-64 disassembler to c++/other languages and first it has alot of instruction codes then it will need to convert to a byte code then im shooting for c++ and javascript output c++ will be one thing but javascript is a completely different story.

 

I will do like swiftcoder mentioned and break it into different classes but just wanted to know what would happen with alot of functions in one class even say the disassembler to bytecode class will need a big switch and I was wanting to handle them in different functions so they can be over ridden and easily find able in a ide. I dont expect this to go anywhere just having my hand at learning more deeply about how everyting on the cpu gets done.


Firefox youtube video and audio downloader MP3 MP4 OGG WEBM

https://addons.mozilla.org/en-US/firefox/addon/simple-youtube-converter/


#8 Aardvajk   Crossbones+   -  Reputation: 5843

Like
5Likes
Like

Posted 18 May 2014 - 12:39 PM

Actually, if there are 2000 different instruction codes and each method is distinct, that's one of the few cases where that could be acceptable. At least then you can map codes to function pointers rather than having a gargantuan switch lookup.

That said, I'd suspect there was a lot of shared functionality on the methods that could've factored down a bit but who knows.

#9 Kaptein   Prime Members   -  Reputation: 1953

Like
2Likes
Like

Posted 18 May 2014 - 03:25 PM

lol well I know it probably not the right way of doing this but im making a x86-64 disassembler to c++/other languages and first it has alot of instruction codes then it will need to convert to a byte code then im shooting for c++ and javascript output c++ will be one thing but javascript is a completely different story.

 

I will do like swiftcoder mentioned and break it into different classes but just wanted to know what would happen with alot of functions in one class even say the disassembler to bytecode class will need a big switch and I was wanting to handle them in different functions so they can be over ridden and easily find able in a ide. I dont expect this to go anywhere just having my hand at learning more deeply about how everyting on the cpu gets done.

 

Considering all this, you may want to constantly reference a profiler for any future changes you make. Identify bottlenecks, evaluate if your code is too complex and figure out where you can make the code easier to read vs where you have to apply performance magic.

If you have to really go all out on a function to make it faster, you can put the old easy-to-understand version of the function in a comment, as sort of pseudo-code and go from there.

 

Some search words and references:

http://en.wikipedia.org/wiki/Branch_misprediction

http://www.ece.unm.edu/~jimp/611/slides/chap5_3.html

http://bigocheatsheet.com/

https://isocpp.org/wiki/faq/inline-functions

 

Ask if you need more specific help, eg with a function that is using too much time.


Edited by Kaptein, 18 May 2014 - 03:30 PM.


#10 NightCreature83   Crossbones+   -  Reputation: 2701

Like
0Likes
Like

Posted 19 May 2014 - 03:31 AM

So just as a reminder to the OP, but a struct is a class in C++, only difference is default visibility level, struct = public, class = private. If those functions are small, the compiler might just end up inlining most of the code anyway in a release build.

 

Still you should probably break this out a bit 2000 functions seems overkill for a class, although it could happen if you have a lot of one or two line functions.


Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#11 samoth   Crossbones+   -  Reputation: 4656

Like
2Likes
Like

Posted 19 May 2014 - 08:54 AM

So just as a reminder to the OP, but a struct is a class in C++, only difference is default visibility level, struct = public, class = private

Heh, this was my first answer-reflex, too. However, on closer inspection, that's not what the OP is asking. The question is not whether there is a difference in having member functions in a struct or class, but rather whether there is a difference between

struct foo{....};
void func1(foo* f);
...
void func2000(foo* f, type bar);

and

class foo
{
    ....
public:
    void func1();
    ...
    void func2000(type bar);
};

Jeff8j: Did I understand that you are basically trying to write a C++ decompiler? Knoweth that this is a daunting endeavour, next to impossible.

Decompiling Java bytecode or such into a human-readable source file is easy (the language is kind of specifically made for that, too). Decompiling C or C++ is harsh. While it is certainly possible to identify things as function prologs and such, there is no way of determining a meaningful variable name of any kind, or a function name (unless these are exported as symbols), no way to reproduce something like template instantiations into something that even vaguely ressembles the original, and no way to restore variables (or sub-expressions) which have been eliminated by compiler optimizations.

In one word, it's pretty much a nightmare...


Edited by samoth, 19 May 2014 - 08:56 AM.


#12 NightCreature83   Crossbones+   -  Reputation: 2701

Like
2Likes
Like

Posted 19 May 2014 - 09:01 AM

 

So just as a reminder to the OP, but a struct is a class in C++, only difference is default visibility level, struct = public, class = private

Heh, this was my first answer-reflex, too. However, on closer inspection, that's not what the OP is asking. The question is not whether there is a difference in having member functions in a struct or class, but rather whether there is a difference between

struct foo{....};
void func1(foo* f);
...
void func2000(foo* f, type bar);

and

class foo
{
    ....
public:
    void func1();
    ...
    void func2000(type bar);
};

Jeff8j: Did I understand that you are basically trying to write a C++ decompiler? Knoweth that this is a daunting endeavour, next to impossible.

Decompiling Java bytecode or such into a human-readable source file is easy (the language is kind of specifically made for that, too). Decompiling C or C++ is harsh. While it is certainly possible to identify things as function prologs and such, there is no way of determining a meaningful variable name of any kind, or a function name (unless these are exported as symbols), no way to reproduce something like template instantiations into something that even vaguely ressembles the original, and no way to restore variables (or sub-expressions) which have been eliminated by compiler optimizations.

In one word, it's pretty much a nightmare...

 

Still the answer to that question is no, effectively this is what a member function does, its first param is the this pointer. So it comes down to how the structure is passed in those functions. If it is by value it is more expensive, because of the copy of the structure, pass by pointer or reference on the first argument to the function it would be the same as a member function.


Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#13 jeff8j   Members   -  Reputation: 710

Like
0Likes
Like

Posted 19 May 2014 - 01:19 PM

Im just doing it to learn more if I get a hello world decompiling ill be happy lol I would like to eventually design a cpu so it would seem important to learn as low a level as possible may I could start off easier with something like a pic microcontroller.

 

I probably will break it up into differnet types/sections/classes I was just starting and was like wait a minute theres a lot of opcodes and system library calls and a world of mess so things are going to be pretty big no matter how I go about them I would think.

 

@samoth yes thats what I was talking about and it will probably only be things I compile going into it so all variables will be know atleast to start with so that should help

 

Im still debating the c route as I could make it compile it self with tiny c compiler and then disassemble it self to recompile again lol but on the downside would probably be harder to write.

 

How much overhead would I encure if I go with c structs with function pointers oviously it would need ints/pointers for each function but would that be al that it needed? Would that get optimized out with full gcc optimization?


Firefox youtube video and audio downloader MP3 MP4 OGG WEBM

https://addons.mozilla.org/en-US/firefox/addon/simple-youtube-converter/


#14 L. Spiro   Crossbones+   -  Reputation: 12873

Like
4Likes
Like

Posted 19 May 2014 - 03:55 PM

lol well I know it probably not the right way of doing this but im making a x86-64 disassembler to c++/other languages and first it has alot of instruction codes then it will need to convert to a byte code then im shooting for c++ and javascript output c++ will be one thing but javascript is a completely different story.
 
I will do like swiftcoder mentioned and break it into different classes but just wanted to know what would happen with alot of functions in one class even say the disassembler to bytecode class will need a big switch and I was wanting to handle them in different functions so they can be over ridden and easily find able in a ide. I dont expect this to go anywhere just having my hand at learning more deeply about how everyting on the cpu gets done.

This is ridiculous. Don’t even break it into multiple classes, use data tables.
I’m the author of MHS (Memory Hacking Software) which has a disassembler and assembler.
http://memoryhacking.com/

Obviously whenever you have 2,000 methods on a class you are doing something wrong, but in this particular case it’s not a matter of breaking into multiple classes etc.; those methods simply should not exist at all, anywhere.
You need to build a data-driven parser using a table such as (partial code from MHS):

DIS_CMD g_cmdData[] = {
	//dwMask	dwCode		L,Bits	Ar1 Ar2 Ar3		ucType				DifopSize		DifAdd	Name			Desc
	{ 0x0000FF,	0x000090,	1,00,	NNN,NNN,NNN,	CD_CMD+0,			FALSE,			FALSE,	"NOP",			"No operation" },
	{ 0x0000FE,	0x00008A,	1,WW,	REG,MRG,NNN,	CD_CMD+0,			FALSE,			FALSE,	"MOV",			"Move [$1] (#1) to $0" },
	{ 0x0000F8,	0x000050,	1,00,	RCM,NNN,NNN,	CD_PSH+0,			FALSE,			FALSE,	"PUSH",			"Push $0 (%0) onto the stack" },
	{ 0x0000FE,	0x000088,	1,WW,	MRG,REG,NNN,	CD_CMD+0,			FALSE,			FALSE,	"MOV",			"Move $1 (%1) to [%0]" },
	{ 0x0000FF,	0x0000E8,	1,00,	JOW,NNN,NNN,	CD_CAL+0,			FALSE,			FALSE,	"CALL",			"Call near, relative, displacement relative to next instruction" },
	{ 0x0000FD,	0x000068,	1,SS,	IMM,NNN,NNN,	CD_PSH+0,			FALSE,			FALSE,	"PUSH",			"Push %0 onto the stack" },
	{ 0x0000FF,	0x00008D,	1,00,	REG,MMA,NNN,	CD_CMD+0,			FALSE,			FALSE,	"LEA",			"Store effective address for [$1] (%1) in register $0" },
	{ 0x0000FF,	0x000074,	1,CC,	JOB,NNN,NNN,	CD_JMC+0,			FALSE,			FALSE,	"JE,JZ",		"Jump short if equal/zero (ZF=1)" },
	{ 0x0000F8,	0x000058,	1,00,	RCM,NNN,NNN,	CD_POP+0,			FALSE,			FALSE,	"POP",			"Pop top of stack (@([ESP])) into $0; increment stack pointer (ESP becomes @(ESP+4))" },
	{ 0x0038FC,	0x000080,	1,WS,	MRG,IMM,NNN,	CD_CMD+1,			FALSE,			FALSE,	"ADD",			"Add $1 to #0" },
	{ 0x0000FF,	0x000075,	1,CC,	JOB,NNN,NNN,	CD_JMC+0,			FALSE,			FALSE,	"JNZ,JNE",		"Jump short if not zero/not equal (ZF=0)" },
	{ 0x0000FF,	0x0000EB,	1,00,	JOB,NNN,NNN,	CD_JMP+0,			FALSE,			FALSE,	"JMP",			"Jump short, relative, displacement relative to next instruction" },
	{ 0x0000FF,	0x0000E9,	1,00,	JOW,NNN,NNN,	CD_JMP+0,			FALSE,			FALSE,	"JMP",			"Jump near, relative, displacement relative to next instruction" },
	{ 0x0000FE,	0x000084,	1,WW,	MRG,REG,NNN,	CD_CMD+0,			FALSE,			FALSE,	"TEST",			"AND %1 with #0 (@(%1&#0)); set SF, ZF, PF according to result" },
	{ 0x0038FE,	0x0000C6,	1,WW,	MRG,IMM,NNN,	CD_CMD+1,			FALSE,			FALSE,	"MOV",			"Move $1 to [%0]" },
	{ 0x0000FE,	0x000032,	1,WW,	REG,MRG,NNN,	CD_CMD+0,			FALSE,			FALSE,	"XOR",			"$0 XOR #1 (=@($0^#1))" },
	{ 0x0000FE,	0x00003A,	1,WW,	REG,MRG,NNN,	CD_CMD+0,			FALSE,			FALSE,	"CMP",			"Compare [$1] (#1) with $0 (%0)" },
	{ 0x0038FC,	0x003880,	1,WS,	MRG,IMM,NNN,	CD_CMD+1,			FALSE,			FALSE,	"CMP",			"Compare %1 with [$0] (#0)" },
	{ 0x0038FF,	0x0010FF,	1,00,	MRJ,NNN,NNN,	CD_CAL+0,			FALSE,			FALSE,	"CALL",			"Call far, absolute indirect, address #0" },
	{ 0x0000FF,	0x0000C3,	1,00,	PRN,NNN,NNN,	CD_RET+0,			FALSE,			FALSE,	"RETN,RET",		"Return to calling procedure (@([ESP]))" },

You need an entirely different approach, and because of your brute-force method you will spend a very long time on this project, gaining virtually nothing from it as a programmer, and all-in-all stunt your growth. You are literally harming yourself if you continue this project.

I would suggest you make 1 or 2 very simple projects that allow you to familiarize yourself with aggregation lists as shown here and restart from scratch your current project. By the time you wrote the first 50 methods by brute force you could have finished the whole project via better knowledge of programming languages.


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#15 Pink Horror   Members   -  Reputation: 1116

Like
0Likes
Like

Posted 19 May 2014 - 07:54 PM

I will do like swiftcoder mentioned and break it into different classes but just wanted to know what would happen with alot of functions in one class even say the disassembler to bytecode class will need a big switch and I was wanting to handle them in different functions so they can be over ridden and easily find able in a ide. I dont expect this to go anywhere just having my hand at learning more deeply about how everyting on the cpu gets done.


Maybe it's unfair or rude to ask this question, but how are you going to write a disassembler if you do not even know how a member function call works? That seems like a basic, low-level thing that anyone working on such a project wouldn't have to ask.

#16 jeff8j   Members   -  Reputation: 710

Like
2Likes
Like

Posted 21 May 2014 - 01:08 PM

@L. Spiro Your absolutely right data tables looks like a much better option! Ill have to read up and start messing around that will probably save alot of work and be simpler Thanks

 

@Pink Horror Im not sure it will get done lol im familiar with how member functions work just not how they get compiled as far as overhead especially for something complicated where it might be harder to optimize down. If I dont try how am I going to learn? For most work I do I do in php that doesnt help make me become a better programmer for the most part lol.


Firefox youtube video and audio downloader MP3 MP4 OGG WEBM

https://addons.mozilla.org/en-US/firefox/addon/simple-youtube-converter/





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS