Jump to content
  • Advertisement
Sign in to follow this  
Ectara

Incrementing operators

This topic is 3034 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I noticed that when I enabled nearest neighbor filtering, my textures showed up grayscale. I looked at the code I wrote, which appeared fine:
	ui8 *pix;
	switch(src->format){
		case E_RGB:
		case E_ANIM_RGB:{
			pix = src->data + (src->frameSize * src->currFrame) + 3*(src->width*(_E_mathRoundf(y)) + _E_mathRoundf(x));
			return _E_eoiD1(*(pix++))|_E_eoiD2(*(pix++))|_E_eoiD3(*(pix))|_E_eoiD4(0xFF);
		}
		break;
		...
	}

The _E_eoiDn macros simply shift the passed value to be the nth byte in the integer. To me, it would seem that it would increment the pointer upon each evaluation of the variable. Apparently that isn't the case; the rewrite I wrote below showed the colors properly, rather than only using one channel for all three.
	ui8 *pix;
	si32 result;
	switch(src->format){
		case E_RGB:
		case E_ANIM_RGB:{
			pix = src->data + (src->frameSize * src->currFrame) + 3*(src->width*(_E_mathRoundf(y)) + _E_mathRoundf(x));
			memcpy(&result,pix,3);
			return result|_E_eoiD4(0xFF);
		}
		break;
		...
	}

So, I suppose my question is, if I have multiple incrementing operators on the same variable at different parts of a statement, is it evaluated and incremented more than once in sequence as I'd expected, or does it do all of the increments prior to evaluating the entire expression?

Share this post


Link to post
Share on other sites
Advertisement
pix++ permanently adjusts the value of pix. So any sucessive access of pix will be of the modified value. They should be incremented in order. But why not just use (pix+1) and (pix+2) then do a pix+=3 at the apropriate time? Seems much more readable that way anyway

-me

Share this post


Link to post
Share on other sites
pix++ also means: use the value of pix then increment it.
++pix means: increment first then use the value.

But yeah... your statement is ridiculously confusing. Why not something like:


case E_ANIM_RGB:{
pix = src->data + (src->frameSize * src->currFrame) + 3*(src->width*(_E_mathRoundf(y)) + _E_mathRoundf(x));
ui8 r = *pix;
ui8 g = *(pix+1);
ui8 b = *(pix+2);
pix += 3;
return _E_eoiD1(r)|_E_eoiD2(g)|_E_eoiD3(b)|_E_eoiD4(0xFF);
}



And also... why are you bitwise or'ing them together?

Share this post


Link to post
Share on other sites
pix is only twice once during this function; once to initialize, once to be evaluated in this returned expression. I've also read that increment operators require one instruction while adding a constant to a variable requires two. Since this function would be called once or twice for every pixel written for every polygon in my renderer, I figured every little bit counts. But the thing that confused me was, I incremented twice in the expression, and rather than incrementing and using the incremented values, it only used one value, as if it added two and used the last value for all three in the evaluation, or used the first then added two.

Share this post


Link to post
Share on other sites
don't optimize before your profiler tells you it's a problem. the compiler is better at optimizing than you anyway. your code is confusing and you can't debug it. make it clean with temp variables and trust that the compiler will make it fast. if it doesn't you can always come back and micro-oiptimze it later.

only pre-increment doesn't require a temp. you're doing post-increment. however, that is "old advice". The compiler will almost always optimize this for you.

-me

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
pix++ also means: use the value of pix then increment it.
++pix means: increment first then use the value.

But yeah... your statement is ridiculously confusing. Why not something like:

*** Source Snippet Removed ***

And also... why are you bitwise or'ing them together?


That would add(assuming a typical stack), three push instructions to allocate the variables, three to assign them, the usual to reference them, then three to pop them off the stack. And I like to OR them together. On some arch's it is simpler than addition.

Share this post


Link to post
Share on other sites
Alright, I chose an alternate method, and I'm guessing the compiler added two and used the original value.

Share this post


Link to post
Share on other sites
Yeah. good plan [smile]

I mean, basically, every piece of advice you've ever heard about arranging code at a micro-level is something that was true maybe 10 years ago. Modern compilers in almost every respect are better than you at that kind of optimization. The only time you should ever worry about details like what you're talking about is if the profiler tells you that piece of code is slow and if you look at the generated assembly and realize that the optimizer has missed something.

-me

Share this post


Link to post
Share on other sites
Thank you, BFG, for answering my question. I even remember reading that FAQ a while back. I'll avoid doing that from now on.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!