Page 2 of 3

Posted: Fri Jun 15, 2007 1:34 am
by AJ
I tried out a 3d desktop replacement for Windows 98, called Doors3D. It was awful - it took me at least 10 times as long to find that program or document I wanted to launch, not to mention I got BSODs even more frequently than when using explorer as the shell.

Never again....

Posted: Fri Jun 15, 2007 9:03 am
by earlz
imo, I don't think that a 3-D desktop can't be useful until we have a 3-D environment in which to use it...right now we would have to make it 3-D and then convert it to be used in a 2-D environment...

Posted: Fri Jun 15, 2007 10:16 am
by Brynet-Inc
Someone build a freaking Holodeck already :P

Wouldn't that be oh so fun? 8)

Posted: Fri Jun 15, 2007 10:34 am
by Tyler
Brynet-Inc wrote:Someone build a freaking Holodeck already :P

Wouldn't that be oh so fun? 8)
I wouldn't enjoy trying to write assembly in 3D... but i can't wait until the first time the safety protocols disengage for no apparent reason and cause my C++ to attack me.

Posted: Fri Jun 15, 2007 12:32 pm
by Alboin
Tyler wrote:but i can't wait until the first time the safety protocols disengage for no apparent reason and cause my C++ to attack me.
I'm pretty afraid of my C... 8-[

With C++, it just shoots you once or twice. With C, it beats you to death with a mallet.

And well...assembly's a little too graphic to post here. :wink:

Posted: Fri Jun 15, 2007 12:49 pm
by earlz
thing about C++ is that it sometimes will give you a false sense of security, so that you think it's workign and everything is protected...then you make some small little change, and it all breaks and you end up having to recode everything

Posted: Fri Jun 15, 2007 4:42 pm
by Kevin McGuire
If you use pointers with C++ overloaded class operators it can get tricky in some moments.

Posted: Fri Jun 15, 2007 5:55 pm
by earlz
If you use pointers with C++ overloaded class operators it can get tricky in some moments.
isn't that taking C++ too far...I personally can't see much any use for many of the operator overloads, and [] I can only see a use for in lists and tables

Posted: Fri Jun 15, 2007 6:08 pm
by Colonel Kernel
hckr83 wrote:
If you use pointers with C++ overloaded class operators it can get tricky in some moments.
isn't that taking C++ too far...I personally can't see much any use for many of the operator overloads, and [] I can only see a use for in lists and tables
operator-> and operator* are very useful for implementing smart pointers. operator() is very useful for implementing functors. +, -, ++ and -- are useful for implementing iterators.

But operator overloading and pointers-to-objects don't mix well syntactically, as you've seen. Use references or just use the objects directly.

Posted: Fri Jun 15, 2007 6:14 pm
by Kevin McGuire
I personally can't see much any use for many of the operator overloads.
Well. I suppose for instance: vector math where you want to make the code a little more readable using some of the syntactic sugar C++ provides.

Code: Select all

class cVec3
{
	public:
	float	x, y, z;
	cVec3();
	cVec3(float _x, float _y, float _z);
	~cVec3();
	cVec3 operator-(const cVec3 &a);
	void debug();
};
cVec3::cVec3()
{
}
cVec3::cVec3(float _x, float _y, float _z)
{
	x = _x; y = _y; z = _z;
}
cVec3::~cVec3()
{
}
void cVec3::debug()
{
	printf("%x: %f,%f,%f\n", this, x, y, z);
}

cVec3 cVec3::operator-(const cVec3 &a)
{
	cVec3 r;
	r.x = x - a.x;
	r.y = y - a.y;
	r.z = z - a.z;
	return r;
}


int main(int argc, char *argv[])
{
	cVec3 a(10.0, 10.0, 10.0), b(2.0, 2.0, 2.0), c;
	/// The entire function call is broken down with optimization turned on (for GCC)
	c = a - b;
	c.debug();
	return 1;
}
As you might notice, it makes writing a statement for doing vector math simpler, and more importantly with optimization enabled the complete function call for the operator overload disappears.

Posted: Fri Jun 15, 2007 6:26 pm
by earlz
Colonel Kernel wrote:
hckr83 wrote:
If you use pointers with C++ overloaded class operators it can get tricky in some moments.
isn't that taking C++ too far...I personally can't see much any use for many of the operator overloads, and [] I can only see a use for in lists and tables
operator-> and operator* are very useful for implementing smart pointers. operator() is very useful for implementing functors. +, -, ++ and -- are useful for implementing iterators.

But operator overloading and pointers-to-objects don't mix well syntactically, as you've seen. Use references or just use the objects directly.
hmm...smart pointers just seem like too much overhead for such a commonly done thing(I tend to use too many pointers though)

function objects?! I didn't even know you could do that! I don't see any practical application right now, but I'm sure there is some good use for it..

++ and -- I can actually see a use for in my list thingy...like being able to override the = operator and such....meh...kidna complicated though..lol

btw, Are templates well optimized? If they aren't, with each call to a template, you'd reproduce code...and with many calls, it could eventually be MBs of duplicate wasted code! (if your not careful)

Posted: Fri Jun 15, 2007 6:29 pm
by Alboin
hckr83 wrote:btw, Are templates well optimized? If they aren't, with each call to a template, you'd reproduce code...and with many calls, it could eventually be MBs of duplicate wasted code! (if your not careful)
I'm pretty sure there's no overhead.

Posted: Fri Jun 15, 2007 6:37 pm
by earlz
edited...

oops..misread things..

Posted: Fri Jun 15, 2007 6:44 pm
by Kevin McGuire
The machine output of using a template function. The part I will show you is where I call MyTest in the main function.

Code: Select all

template <class TYPE> TYPE MyTest(TYPE& a)
{
	return a;
}

int main(int argc, char *argv[])
{
	float a;
	unsigned int b;

	a = MyTest<float>(a);
	b = MyTest<unsigned int>(b);	
	return 1;
}

Here is the machine output for the main function. You should notice two instructions in italic and bold. They are the calls I made the C source to our MyTest function template. The interesting part is that you might mistakenly identify them as the same call but if you look closely you can see that the letter f in the first function name is replaced with a letter j in subsequent template function call. This means the compiler took our one template function and produced a version for each template parameter list we called it with.
lea 0x4(%esp),%ecx
and $0xfffffff0,%esp
pushl 0xfffffffc(%ecx)
push %ebp
mov %esp,%ebp
push %ecx
sub $0x14,%esp
lea 0xfffffff8(%ebp),%eax
mov %eax,(%esp)
call 8048420 <_Z6MyTestIfET_RS0_>
fstps 0xfffffff8(%ebp)
lea 0xfffffff4(%ebp),%eax
mov %eax,(%esp)
call 8048434 <_Z6MyTestIjET_RS0_>
mov %eax,0xfffffff4(%ebp)
mov $0x1,%eax
add $0x14,%esp
pop %ecx
pop %ebp
lea 0xfffffffc(%ecx),%esp
ret
Here are the two functions it produced just so you can notice it only created one instance of each.
08048420 <_Z6MyTestIfET_RS0_>:
8048420: 55 push %ebp
8048421: 89 e5 mov %esp,%ebp
8048423: 83 ec 04 sub $0x4,%esp
8048426: 8b 45 08 mov 0x8(%ebp),%eax
8048429: 8b 00 mov (%eax),%eax
804842b: 89 45 fc mov %eax,0xfffffffc(%ebp)
804842e: d9 45 fc flds 0xfffffffc(%ebp)
8048431: c9 leave
8048432: c3 ret
8048433: 90 nop

08048434 <_Z6MyTestIjET_RS0_>:
8048434: 55 push %ebp
8048435: 89 e5 mov %esp,%ebp
8048437: 8b 45 08 mov 0x8(%ebp),%eax
804843a: 8b 00 mov (%eax),%eax
804843c: 5d pop %ebp
804843d: c3 ret
804843e: 90 nop
804843f: 90 nop
So no it does not continually add overhead each time you make a function call, instead it just creates one instance of this function in machine output.

The compiler may inline a template function, but it may also inline a non-template function. GCC has algorithms to determine when to and when not to inline. (I have no in depth understanding of this mechanism).

And, GCC will optimize a instance of a template function just like a normal function..

Posted: Fri Jun 15, 2007 9:20 pm
by Colonel Kernel
hckr83 wrote:hmm...smart pointers just seem like too much overhead for such a commonly done thing(I tend to use too many pointers though)
What is such a commonly-done thing? Calling new and delete? Managing reference counts...? The overhead added by a smart pointer is negligible, because any worthwhile compiler will inline most of the smart pointer's methods. On the other hand, the benefits of using smart pointers are tremendous as they make it much more difficult to inject subtle memory leaks into your code during development.
function objects?! I didn't even know you could do that! I don't see any practical application right now, but I'm sure there is some good use for it..
You should spend some time learning how to use the algorithms in the STL. In a nutshell, function objects make it easy to apply a custom operation over a collection in a generic way. For example, let's say you have a vector<Foo*>, and each Foo has a method getBar() that returns a pointer to the Bar belonging to that Foo. If you want to "strip" the Foos off and end up with a vector<Bar*>, you can do that easily by writing a short function object that just calls getBar() on a Foo, and then call std::transform() on your input and output vectors. It's quite nifty, at least for C++.

This kind of technique is actually extremely common in functional programming languages, but they offer much better support for such things directly in the language via "lambda functions" (I don't want to oversimplify too much, but basically they're anonymous functions).
++ and -- I can actually see a use for in my list thingy...like being able to override the = operator and such....meh...kidna complicated though..lol
Yeah, iterators are complicated to implement properly. I wouldn't even bother. The point is that without overloading operator ++ and -- it would be impossible for the STL to provide generic algorithms that work on all kinds of containers, including plain-jane C arrays. But as far as implementing iterators goes, better the STL guys than me. :P
btw, Are templates well optimized? If they aren't, with each call to a template, you'd reproduce code...and with many calls, it could eventually be MBs of duplicate wasted code! (if your not careful)
In terms of speed, templates are very well optimized. Everything basically gets inlined. In terms of space, if you instantiate a template with many different types, then yes, it can consume a lot of space. As others have said, it's not per "call" though, it's per unique instantiation. For example, if you have a vector<Foo> and a vector<Bar>, the code for vector will be replicated once for each.

I've heard horror stories about crappy old C++ compilers on really old flavours of UNIX (which, unfortunately for me, are still in active use) that will copy template code for a particular instantiation once per .cpp file, and the linker fails to eliminate the duplicate code. I haven't verified this myself yet though.