For the sake of temporary variables...

Started by
6 comments, last by _cdcel 16 years, 4 months ago
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?
Advertisement
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.
Quote:Original post by Brother Bob
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.


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"?
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.
-Mike
Since you're using C++ ideas like operator overloading, why not:
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.
Quote:Original post by Anon Mike
I 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.

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.
(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 );	}};

This topic is closed to new replies.

Advertisement