Parameter-Based Argument Sending

Started by
11 comments, last by zozzaloka 8 years, 7 months ago

hi I recently imagined a model of parameter-based argument sending worrying about how I deal with memory management.

so I want your some opinions. smile.png

1. all type of sending argument to functions have only one data for labeled parameter like this,

struct STD_PARAM
{
   int num_param[5] ;
   char str_param[10] ;
....
}; 
struct STD_PARAM fordata_param ;
void func_a ()
{
   int data0 = fordata_param.num[0] ;
   int data1 = fordata_param.num[1] ;
...
}
void func_b ()
{
   int foradd = fordata_param.num[0] ;
   int formultiple = fordata_param.num[1] ;
....
}

2. all functions should have a consistent rule for using parameter of course all rules should explicate their purposes manifestly.

so I can get some concludes

1) consecutively defined ( assigned / released ) data can be avoided.

2) all functions can freely get data ( return data use pointer or direct return )

3) this can cause many confusions of purpose occasionally

I'll wait your some opinions hopefully. smile.png

Advertisement

If one function calls another function then it must reset the 'fordata_param' struct, which means it must copy and remember its own parameters that it might need later. So I don't see the point of your method.. it does the same as the normal stack but with an extra route through temporary storage, and is likely to make everything more difficult for the compiler to optimize.

If one function calls another function then it must reset the 'fordata_param' struct, which means it must copy and remember its own parameters that it might need later. So I don't see the point of your method.. it does the same as the normal stack but with an extra route through temporary storage, and is likely to make everything more difficult for the compiler to optimize.

thanks I just want to see its usage. through your saying,It has no meaningful things except some special occasions.

Can you explain what advantages you were thinking this might have, more specifically? I didnt quite get it...

Isnt this basically how classes and class member functions work though? In some cases I create a temporary "parameter holding" class if its likely that I will call many functions which all need same parameters consequtively. So I just need to pass the params once to the constructor, then call the many functions. Just for convenience, not performance. Although it creates opportunity to cache some values so they can be shared by the multiple function calls. (These helper classes are supposed to be stack-allocated temporaries, not stored anywhere)

Its also common to pack parameters in a struct or class and passing that, instead of passing each separately (assuming there exists a logical grouping of some kind)

Dont worry about performance, the compiler will do heavy optimization to avoid doing any more work than required in common operations like this. If it would be easy to avoid the costs by using an alternative method like this and it was actually worth it, the compiler would probably already do it behind the scenes.

o3o


Can you explain what advantages you were thinking this might have, more specifically? I didnt quite get it...

yep exactly It can provide advantages of coding with consistent rule not performance like high speed or abundant free memory.smile.png

Consider the impact of this system on situations such as...

* Recursion: you often have to temporarily save copies of fields into local variables, which means copying them to the stack... where they would have been if you passed them in traditionally.

* Mutual calls: if a method using that structure has to call another, it has to either save some fields to locals, or rewrite the structure entirely for the second call.

* Parallel processing: ohgodwhy

* Change management: if the arguments to a function change, you can't merely find all references to that function and update them; the actual code to be affected will be spread throughout various bodies leading up to the calls.

What you've laid out is pretty normal for extremely embedded systems where you have a hardware stack (which can only hold return addresses) or otherwise highly limited stack memory (e.g. only dozens to hundreds of bytes of stack space, instead of thousands to millions)... but those kinds of systems' software is usually developed under very rigid change controls, where ideally 100% of the program is documented and planned out and constraint-optimized, before even a single line of code is written.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

Look into "unions", those are sometimes used to allow the same data struture to be interpreted in different ways (in some ways like what you are doing?) except its better since you still have named variables with a type (except variables might share the same bytes)

Its good to add some methods to operate on that data though, to avoid mistakes. You can even add extra debug-only variables to allow doing runtime checks when in debug mode (probably disabled in release version).

Though dont use a global variable. Either have the stuff as a class member, or pass by parameter. Globals are bad mkay.

Using unions to 'share memory' in this way is usually just for performance though. So its mostly used in places where youre dealing with A LOT of data (think input event messages, or tiles/voxels in game map)

o3o

It isn't clear what problem you're trying to solve. You mention "worrying about how I deal with memory management", maybe if you explain this worry in more detail your proposal will be clearer?
thanks for your opinions actually I believed it gives no allocating memory in very frequently called functions with an advantage of no modifying argument label when changing original function structure. but especially in deburging I realized it can cause a big chaos to argument reference

My rule is..

1) Pass everything you need in

2) Do work then return the result

3) Avoid side effects

With these you can compose your functions together. With methods (return void) you cant chain or compose them and everything you do is about side effects.

Your system as other have highlighted blocks recursion and also hides everything away so you have to read the functions code to see what it is working on and even how to call it.

It will also have huge issue with threading as the function is not reentrant, it will be impossible for more than one thread to call any of the functions at the same time. Even worse, a thread will be unable to call func_b if another thread is in func_a. The more you use this technique on your methods the worse it will become, a true locking nightmare

I believe if you use this you will find you have boxed yourself into a bad space later down the line

The reality is if you are passing stuff in that is just stack space, which will still be used (just not as much) for the call context. So you have switched cheap stack usage for 2 levels of indirection to access values.

This topic is closed to new replies.

Advertisement