reason to pass values byval/byref

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
Wundersam

reason to pass values byval/byref

Post by Wundersam »

Hello,

studying the sourcecode I stumbled across several methods that require
arguments to be passed byval. Others however use byref. I couldn't see
any real consistency here so my question is: Is there any particular reason
for this that I don't see?

Also, doesn't byval come with a certain performance hit?


Sorry if I'm sounding dumb.

Thank you in advance!
schick
Posts: 230
Joined: Tue Oct 07, 2003 3:55 pm
Location: Germany
Contact:

Post by schick »

Passing by value means to copy the parameter instead of using a "pointer" to it.
Please send me an e-mail instead of a private message.
katoun
Posts: 239
Joined: Mon Nov 15, 2004 9:39 am
Location: Romania
Contact:

Post by katoun »

Yes but pointers are transmited byval too when byref works alot diferent.
Besides both have theyr reason at the corect moment:
With pointers you can point to a memory location or create(alocate the memory with a val) when byval you must 'point' to an existing memory location.
With pointers you alocate memory (even it is a relative small compare with complex data structures) an a lot ov pointers mean more memory used while a byref value mean actualy the pointer to an allready alocated data(when you alocate a data like:" int a=2; " a has actulay the pointer to the memory loaction of that value then: " int* p=&a" alocates memory but : "int& r=a;" you actualy use the same pointer that originaly was created to acces the 2 value but it only has a differrent name so r is the same to a in words of memory location while p is something different) :D
Kat'Oun
Wundersam

Post by Wundersam »

Thank you for your answers! :D

Well, I know the difference between passing an argument by reference
and passing it by value. I only wonder why Irrlicht is using byval at all.

Needing to preserve the passed arguments is merely a matter of design,
isn't it? IIRC I found places in the code where byval isn't necessarily needed
but could improve speed when exchanged by byref, that's why I asked for the
particular reasons. Searching this forum I found other threads in which users
experimented with replacing byref by byval, stating they experienced some
perfomance gain. Don't get me wrong, I only wonder why Irrlicht is designed
the way it is designed. I do really like Irrlicht yet want to find out if I'm missing
something. :)

Thanks again.
katoun
Posts: 239
Joined: Mon Nov 15, 2004 9:39 am
Location: Romania
Contact:

Post by katoun »

Well you must consider it is a huge source code for one person to control.
To make optimizations for it it realy neads alot of time (a lot ) to trace throw the code and see how data is manipulated and for one person that it would be more like Sisific effort than a nightmare. :(
I think that the comunity would have to do, each a part of it and save the 'upgrades' somewhere everybody would have acces to it so Niko or somebody else could put it togather.
Kat'Oun
Wundersam

Post by Wundersam »

Good points, katoun, I see what you mean.

Still I'm wondering why Niko decided to do it the way he did at all.
Well, that's just me. ;) And of this course doesn't change anything
to the fact that Irrlicht is a really really cool engine.

Thank you for your answer! :D
Wundersam

Post by Wundersam »

Good points, katoun, I see what you mean.

Still I'm wondering why Niko decided to do it the way he did at all.
Well, that's just me. ;) And of this course doesn't change anything
to the fact that Irrlicht is a really really cool engine.

Thank you for your answer! :D
FlyHigh
Posts: 111
Joined: Wed Mar 23, 2005 12:05 am

Post by FlyHigh »

If i'm not mistaken references and pointers produces the same output from the compiler, just using references enforces that the what it points to wont be re-assigned or null.
Guest

Post by Guest »

FlyHigh wrote:If i'm not mistaken references and pointers produces the same output from the compiler, just using references enforces that the what it points to wont be re-assigned or null.
How should the compiler do this without producing different code? ;)

Let's assume the following:

Code: Select all

struct vector3df {
	float x,y,z;
};

void ByVal(vector3df vec)
{
}

void ByRef(vector3df& vec)
{
}
The generated ASM (VC++ output) for ByVal looks like this:

Code: Select all

	sub	esp, 12
	mov	eax, esp
	mov	ecx, DWORD PTR _myVec$[ebp]
	mov	DWORD PTR [eax], ecx
	mov	edx, DWORD PTR _myVec$[ebp+4]
	mov	DWORD PTR [eax+4], edx
	mov	ecx, DWORD PTR _myVec$[ebp+8]
	mov	DWORD PTR [eax+8], ecx
	call	?ByVal@@YAXUvector3df@@@Z
	add	esp, 12
The corresponding ByRef-Code looks like the following:

Code: Select all

	lea	eax, DWORD PTR _myVec$[ebp]
	push	eax
	call	?ByRef@@YAXAAUvector3df@@@Z
	add	esp, 4
Maybe you mean "Const" ?
hybrid

Post by hybrid »

FlyHigh mentioned byReference and byPointer. This is indeed very similar, but of course the additional checks need some additional overhead.
But this discussion is really dependent on the types we're talking about. Assume you have three floats to pass, it would not make any difference to pass them by value. At least for the amount of data pushed to the stack. If you want to change these variables in the caller's context, however, you must pass by reference. There was a similar discussion on whether vector3df should be passed by 3 floats or one object (reference). There had been some advantages in speed for the 3 floats, but they were so small that the loss of clean API would be more severe.
I would like to know which code frgaments originally lead to this thread, because it is always possible to have some improper function parameters.
Wundersam

Post by Wundersam »

hybrid wrote:There was a similar discussion on whether vector3df should be passed by 3 floats or one object (reference). There had been some advantages in speed for the 3 floats, but they were so small that the loss of clean API would be more severe.
You're right, passing 3 floats will be faster but still definitively not nice to use, especially when you've got functions that require a vector for direction, position, size, etc. Using a structure here makes more than sense of course (overhead or not).

Still it's a difference whether you pass the structures byref or byval.
I would like to know which code frgaments originally lead to this thread, because it is always possible to have some improper function parameters.
Nothing in particular, really. Reading the source just made me wonder why arguments are both passed by value and by reference. I couldn't see any real thread in this.

Just an example (maybe not the best):

Code: Select all

//
// IParticleSystemSceneNode.h
//
	virtual IParticleEmitter* createBoxEmitter(
		core::aabbox3d<f32> box = core::aabbox3d<f32>(-10,28,-10,10,30,10),
		core::vector3df direction = core::vector3df(0.0f,0.03f,0.0f), 
		u32 minParticlesPerSecond = 5,
		u32 maxParticlePerSecond = 10,
		video::SColor minStartColor = video::SColor(255,0,0,0),
		video::SColor maxStartColor = video::SColor(255,255,255,255),
		u32 lifeTimeMin=2000, u32 lifeTimeMax=4000,
		s32 maxAngleDegrees=0) = 0;
Why pass "box" and "direction" by value? Why do these values need to be preserved?

Please don't get me wrong, I'm not saying "Hey, I'm right, you're wrong".
I've got the feeling I'm missing something here and I'd simply like to fully understand this. :)
Guest

Post by Guest »

Try compiling this:

Code: Select all

float do_something(float &x)
{
 return x;
}

main()
{
 float x,y,z;

 x=4;
 y=5;

 z=do_something(x+y);
}

Guest

Post by Guest »

In other words: if you want really readable code, sometimes you can't avoid passing by value because of compiler limitations.
Wundersam

Post by Wundersam »

Good explanation, Guest! :)

IMHO that still doesn't explain the entire subject but that's enough info for me now.
Thanks!
Post Reply