Jump to content

Pass By Reference Generates Huge Code


Recommended Posts

Hi,

 

Got all excited when I saw pass by reference in 6.11 release. I use a lot of pointer stuff to pass references to structures into functions at the moment, and thought pass by reference would produce much less code.

 

But it looks like the compiler still makes a temporary copy of the variables passed into the functions. Its just that after the function call it copies the temporary variable back to the original.

 

So the code size for the function call gets roughly doubled.

 

Does it have to be like this, or can you generate the code for the function using the actual address of the variable that was passed by reference (so the function acts directly on the variable rather than on a copy).

 

Not complaining though.. Its a great compiler and IDE, and since pass by reference is actually C++ functionality its a useful bonus for us C users..

 

regards

 

Chris.

Link to post
Share on other sites
Got all excited when I saw pass by reference in 6.11 release. I use a lot of pointer stuff to pass references to structures into functions at the moment, and thought pass by reference would produce much less code.

 

But it looks like the compiler still makes a temporary copy of the variables passed into the functions. Its just that after the function call it copies the temporary variable back to the original.

 

So the code size for the function call gets roughly doubled.

 

Does it have to be like this, or can you generate the code for the function using the actual address of the variable that was passed by reference (so the function acts directly on the variable rather than on a copy).

 

Not complaining though.. Its a great compiler and IDE, and since pass by reference is  actually C++ functionality its a useful bonus for us C users..

 

You are correct describing how pass by reference works. There is no way using PIC instruction set to pass variable directly into a function. Consider that the same function gets called from different places. How will you manage variables passed by reference from every such call?

 

Regards,

Pavel

Link to post
Share on other sites
You are correct describing how pass by reference works. There is no way using PIC instruction set to pass variable directly into a function. Consider that the same function gets called from different places. How will you manage variables passed by reference from every such call?

 

Regards,

Pavel

 

Hi Pavel,

 

I see. But its going to catch people out if they use a reference to a hardware register and try and do something to it inside the function. I'm not sure I can see any real advantage in using pass by reference when its done like this (and potential confusion).

 

I guess the compiler could create a new instance of the function for each call that uses a different reference value. The code would get bigger, but it would be more true to the idea.

 

Alternatively just treat the reference as though it were passed as an address pointer.

 

You could use the first approach if the function is defined as inline and the second otherwise.

 

I'm off to continue my quest for casting reference variables on the Enhancements thread now.

 

Thanks and Regards

 

Chris

Link to post
Share on other sites

Chris,

 

I see. But its going to catch people out if they use a reference to a hardware register and try and do something to it inside the function. I'm not sure I can see any real advantage in using pass by reference when its done like this (and potential confusion).

 

What needs doing here is limiting the passing by referwnce arguments to non-volatile data type, ie data that is not related to a port or periheral, as these as you point out won't work as expected.

 

Regards

Dave

Link to post
Share on other sites
Chris,

 

I see. But its going to catch people out if they use a reference to a hardware register and try and do something to it inside the function. I'm not sure I can see any real advantage in using pass by reference when its done like this (and potential confusion).

 

What needs doing here is limiting the passing by referwnce arguments to non-volatile data type, ie data that is not related to a port or periheral, as these as you point out won't work as expected.

 

Regards

Dave

 

Or used by interrupts or any other execution thread...

Link to post
Share on other sites
  • 1 year later...
Chris,

 

I see. But its going to catch people out if they use a reference to a hardware register and try and do something to it inside the function. I'm not sure I can see any real advantage in using pass by reference when its done like this (and potential confusion).

 

What needs doing here is limiting the passing by referwnce arguments to non-volatile data type, ie data that is not related to a port or periheral, as these as you point out won't work as expected.

 

Regards

Dave

 

Or used by interrupts or any other execution thread...

 

For an otherwise outstanding product, I'm disappointed! I just got caught by this of the form :( where the signature is f( bit &abit) where abit is volitile. Calling this feature "pass by reference" is deeply misleading. It is correctly called "return parameter result into variable" and is not part of ANSI "C" or even C++. What is misleading here is the lack of precise documentation of this behavior along with the use of the standard syntax normally used for passing by reference in C++. At minimum a warning of this aberrant behavior should be given. I recommend that you either implement it correctly or remove it. Otherwise is will cost hours of needless debugging because a knowledgeable C/C++ developer will assume from the imprecise documentation and the familiar syntax that it really is "call by reference". This is an example of getting caught by the classic compiler writer's dilemma. "If I can implement something with most but not all of the capability of a standard language feature, should it look like the standard feature?" I would suggest that the answer to this question is "NO" until you can replace "most but not all" with "all". Only then does it become "yes" modulo bugs and implementation limitations. The fall back position should always be to issue a warning as this compiler does on many other occasions.

 

The correct way to implement call by reference is to pass an lvalue (i.e. pointer) of the called variable into the function and dereference the lvalue where required. I.E:

 

void f( bit &abit) { while ( abit ) ; } which is called with f( mybit ) is equivalent to:

 

void f( bit *abit) { while( *abit ); } which is called with f( &mybit ).

 

The compiler notes the "reference" parameter in each function signature, computes the lvalue of each reference parameter and passes the parameter lvalues into the function body. [Of course, the lvalue in the example is the byte address of the bit coupled with the bit number.] The function body is then compiled where each right hand side appearance of the reference parameter is replaced by the dereferenced lvalue. Each left hand side appearance is simply the lvalue as in normal "C" compilation. Calls of the function then (e.g. f(mybit);) are replaced with the computed lvalue ( e.g. bit *pMybit = &mybit; f( pMybit); ). In the case of the PIC processors (16 and 18) I suspect that the compiled code will be definitely larger than using call-by-value parameters. However, the savings comes from many calls to the general function as opposed to replicating the function code at each call point in the program.

 

A good example of this is the I2C functions in "i2c.h". There are many replications of the two phrases:

 

while (l_acken || l_rcen || l_pen || l_rsen || l_sen || l_rw || !l_sspif)
		if (T_MODE & i2c_reset_wdt)
			clear_wdt();

 

while (l_acken || l_rcen || l_pen || l_rsen || l_sen || l_rw )
		if (T_MODE & i2c_reset_wdt)
			clear_wdt();

 

where each of the l_<bitname> are volatile being in (M)SSP registers. They could be replaced by overloaded functions:

 

void i2cWAIT( void ) { ... }

void i2cWAIT( bit #abit ){ ... }

 

for considerable code savings. Of course, the second function will not compile correctly :blink: .

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...