# For the sake of temporary variables...

## Recommended Posts

_cdcel    114
Consider:
/* class v2 { double x, y; ... }; */

/* #1) */
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 );
printf( "The resulting vector is <%.3f %.3f>", vtemp.x, vtemp.y );

/* #2) */
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 );
printf( "The resulting vector is <%.3f %.3f>", vtemp );

/* #3) */
printf( "The resulting vector is <%.3f %.3f>", v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ) );

/* (Each produces the same output) */


Which would you prefer?

##### Share on other sites
Brother Bob    10344
I prefer the first one, as the second and third relies on undefined behaviour. You cannot safely pass non-trivial types to functions using variable number of arguments if I remember correct.

##### Share on other sites
_cdcel    114
Quote:
 Original post by Brother BobI prefer the first one, as the second and third relies on undefined behaviour. You cannot safely pass non-trivial types to functions using variable number of arguments if I remember correct.

But wouldn't the program write the contents of the class into the va_list anyways? Therefore, wouldn't it be safe to say "%f %f" expects two consecutive doubles, which is also a "v2"?

##### Share on other sites
Anon Mike    1098
Not necessarily no. Some compilers/architectures treat structs/classes passed by value in wierd ways. I wouldn't be the least bit surprised if your code doesn't work on ia64 for example.

You are firmly in undefined territory here.

##### Share on other sites
d000hg    1199
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ); cout << "The resulting vector is " << vtemp );

Or if you really dislike c++ streams, a better way to engineer your v2 might be to do:
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ); printf("The resulting vector is %s", vtemp.toString());
Of course you have to add a toString() method for v2... but then it's likely that being able to serialize a v2 object might be useful anyway.

##### Share on other sites
Brother Bob    10344
Quote:
 Original post by Anon MikeI wouldn't be the least bit surprised if your code doesn't work on ia64 for example.

Just tried it on x64 in VC8 and it actually didn't work.

##### Share on other sites
Zahlman    1682
If you were actually writing code in a sane way using type-safe library functions, the last would be what you want. In idiomatic C++:

cout << "The resulting vector is " << (v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ));

Naming things implies that they're important enough to be named. If you're only going to write the expression once and use its value once, it is unlikely to be that important.

Of course, context is everything: normally you would want to subtract vectors that *already existed* for some reason, so those variables would already be there. But there would still be no reason to explicitly declare a variable to represent their difference.

##### Share on other sites
_cdcel    114
(Not a big fan of cout; I find it unnecessarily elaborate.)

I want to get rid of the temporary variables if I can, so I don't have to declare "vtemp" everytime...

I guess toString() suits my needs the best...
class v2 {public:/* ... */	std::string toString( const char *form = "<>", unsigned int perc = 3 )	{#ifdef _DEBUG		assert( strlen( form ) > 1 );#endif		/* std::string ztl::format( char *format, ... );		   step 1: "%c%%.%uf %%.%uf%c" -> "<%.3f %.3f>"		   step 2: "<%.3f %.3f>" -> "<x y>" */		return ztl::format( ztl::format( "%c%%.%uf %%.%uf%c", form[0], perc, perc, form[1] ).c_str(), x, y );	}};