IMG_SP_EMPTY_SPACE = what?

Discussion around programming R'n'D, its source code and its tools.

Moderators: Zomis, Flumminator

Post Reply
User avatar
Zomis
Posts: 1501
Joined: Mon Jun 21, 2004 1:27 pm
Location: Sweden
Contact:

IMG_SP_EMPTY_SPACE = what?

Post by Zomis » Sat Jun 10, 2006 4:32 pm

main.h, line 34:

Code: Select all

#define IMG_SP_EMPTY			IMG_SP_EMPTY_SPACE
So, where can the value of IMG_SP_EMPTY_SPACE be found? I can't find it anywhere! But I'm guessing it's zero...

HerzAusGold
Posts: 322
Joined: Sun Sep 25, 2005 4:41 pm
Location: Germany

Post by HerzAusGold » Sat Jun 10, 2006 5:13 pm

Both macro's are not used in the code.

by the way:
If a define have no corresponding definition the preprocessor replace
it with nothing.
If you find such a define there is a second possibility:
The define is used as compile switch.

But the defines you found are never used.
And the answer is ... 42 !

User avatar
Zomis
Posts: 1501
Joined: Mon Jun 21, 2004 1:27 pm
Location: Sweden
Contact:

Post by Zomis » Sat Jun 10, 2006 6:11 pm

If they're not used, then why are they there? Doesn't the C compilator complain also when it's not used?

Could someone explain this to me too?

Code: Select all

SET_CHANGE_EVENT(e,c,v)  (IS_CUSTOM_ELEMENT(e) ?        CH_EVENT_VAR(e,c) = (v) : 0)
If element e is a custom element, then set CH_EVENT_VAR(e,c) to the value of v??? totally confused!
If element e is NOT a custom element, then return 0.

HerzAusGold
Posts: 322
Joined: Sun Sep 25, 2005 4:41 pm
Location: Germany

Post by HerzAusGold » Sat Jun 10, 2006 7:13 pm

This depends:
- if something like this is used in a assignment
it assign 0 to the right value.

- if only a call the 0 do nothing (it's a NOP in assembler)
it is the short form for a if clause
For this operator you must have a third "argument"

Here I think it is a "no operation"
If there is a custom element the next statement (macro) is executed.
You have to look what this macro is defined for.
If there is not a custom element - no operation

here it is the CH_EVENT_VAR macro is replaced - (element is a CE) - with leads to this:

Code: Select all

(element_info[e].change->has_event[c]) = (v)
other Example:

Code: Select all

k = (i < 8) ? i=5 : 0;    // 0 is assigned to k (if i >= 8)

(i < 8) ? i=5 : 0;          // 0 do nothing


if (i < 8) {
    i=5;
} else {
    0;
}
If they're not used, then why are they there?
dark corners after 10 years of development (or may be for the future?)
Doesn't the C compilator complain also when it's not used?
Not for "defines"
And the answer is ... 42 !

HerzAusGold
Posts: 322
Joined: Sun Sep 25, 2005 4:41 pm
Location: Germany

Post by HerzAusGold » Sun Jun 11, 2006 7:52 am

Hope the above helps.
If not take in mind that if there are macro's in the code,
the preprocessor makes only textual replacements.

Example:

Code: Select all

#define QUAD(x)    x*x

  a = QUAD(5);      // leads to "a = 5*5;"

  a = QUAD(4+2);   // leads to "a = 4+2*4+2;"
                            // this is not what you expect !!
                            // the result is not 36
                            // it is 14 !!

// so better is this
#define QUAD(x)   ((x)*(x))

  a = QUAD(4+2);   // now leads to "a = ((4+2)*(4+2));"
                            // result is now 36

// but be warned you can have sideeffects 
 
  a = QUAD(x++);    // leads to "a=((x++)*(x++))"
   
guess what happen if x = 3 at beginning.
And the answer is ... 42 !

User avatar
Zomis
Posts: 1501
Joined: Mon Jun 21, 2004 1:27 pm
Location: Sweden
Contact:

Post by Zomis » Mon Jun 19, 2006 8:21 pm

After reading through your posts a few times, I now think I got it...

Code: Select all

#define CH_EVENT_VAR(e,c)		(element_info[e].change->has_event[c])
#define CH_ANY_EVENT_VAR(e,c)		(element_info[e].has_change_event[c])

#define SET_CHANGE_EVENT(e,c,v)		(IS_CUSTOM_ELEMENT(e) ?		\
					 CH_EVENT_VAR(e,c) = (v) : 0)
#define SET_ANY_CHANGE_EVENT(e,c,v)	(IS_CUSTOM_ELEMENT(e) ?		\
					 CH_ANY_EVENT_VAR(e,c) = (v) : 0)
Could then be written like this in more human understandable code:

SET_CHANGE_EVENT(e,c,v):
if IS_CUSTOM_ELEMENT(e) then
element_info[e].change->has_event[c] = v;
else do nothing;

SET_ANY_CHANGE_EVENT(e,c,v):
if IS_CUSTOM_ELEMENT(e) then
element_info[e].has_change_event[c] = v;
else do nothing;

x = 3;
a = QUAD(x++); // leads to "a=((x++)*(x++))"
a == 5*6 == 30?
or maybe only 4*5 == 20?
Depending on whether to execute the "x++" inside QUAD() or not. But I think it does gets executed... but if it gets executed then it should be replaced with 4... so then a would become 16... but it's probably more advanced like that...
maybe it even becomes BOTH 3 and 4? Naaah... it couldn't... or could it?
Please, answer please :) I don't have a C compiler to test the code on :P

User avatar
Holger
Site Admin
Posts: 2904
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Post by Holger » Mon Jun 19, 2006 10:35 pm

> Could then be written like this in more human understandable code:
[...]

Yup, exactly right!

>> x = 3;
>> a = QUAD(x++); // leads to "a=((x++)*(x++))"
> Depending on whether to execute the "x++" inside QUAD() or not. But I
> think it does gets executed... but if it gets executed then it should be
> replaced with 4... so then a would become 16... but it's probably more
> advanced like that...
> maybe it even becomes BOTH 3 and 4? Naaah... it couldn't... or could it?

It works like that: "x++" just means the following: Evaluate x and then increment x by one. In comparison, "++x" means: "Increment x by one and then evaluate x.

Therefore, "x=3; a=((x++)*(x++))" results in x being evaluated ("3"), then incremented by one ("4"), then evaluated again ("4") and finally again incremented by one ("5"). So the rvalue (right value) expression evaluates to "3 * 4", and the value of x is 5 afterwards (while the caller of that macro might expect a value of 3*3 for a and a value of 4 for x after that expression, just as it would be if it wasn't a C preprocessor macro, but an ordinary C function.

HerzAusGold
Posts: 322
Joined: Sun Sep 25, 2005 4:41 pm
Location: Germany

Post by HerzAusGold » Tue Jun 20, 2006 7:25 pm

Therefore, "x=3; a=((x++)*(x++))" results in... 3*4 ...
Sorry, that's wrong! :shock:
a) x=3;a=QUAD(x++); // results in a = 3*3 = 9, x = 5
b) x=3;a=QUAD(++x); // results in a = 5*5 = 25, x = 5

a) first the multiplication is done, then the assigment, then the both (past)increments.

b) first the both (pre) increments are done, then multiplication, then the assignment.

May be this depends on the compiler, but this is the way the things should go. Check out a new project and test it. :)
And the answer is ... 42 !

User avatar
Holger
Site Admin
Posts: 2904
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Post by Holger » Tue Jun 20, 2006 9:51 pm

> Sorry, that's wrong! Shocked

Whoops! You're right! :-o

> a) x=3;a=QUAD(x++); // results in a = 3*3 = 9, x = 5
> b) x=3;a=QUAD(++x); // results in a = 5*5 = 25, x = 5

Just tested this -- indeed... :-o

> a) first the multiplication is done, then the assigment, then the both
> (past)increments.
>
> b) first the both (pre) increments are done, then multiplication, then the
> assignment.

That's funny! I really was sure that the two post-increments would be done within the left-to-right evaluation of that expression from the expanded pre-processor macro -- seems that I learned something new about C after 19 years of programming that language! :-D (Probably that's because I only use such post-increments in the very obvious cases like "for(i=0;i<x;i++)" or "*dest++=*src++", where the latter example should have prevented me from making the above assumption... :-) )

And it's also a good example what *not* to do in C (unless you want to confuse those who later read your code). ;-)

> May be this depends on the compiler, but this is the way the things
> should go. Check out a new project and test it. Smile

Yep! And I'm sure that this is handled exactly the same by all C compilers -- I should have tried this with compiled code before posting! (I should start buying a sixpack of beer for you now, I think... ;-) ) As far as I know, all relevant C compilers handle such "dirty" stuff exactly the same (even crazy things like "Duff's Device" work with all C compilers!). BTW: I think there should be a new R'n'D element called "McDuffin's Device" doing strange things. Maybe it's also a good second name for CEs in general... :-D

User avatar
Holger
Site Admin
Posts: 2904
Joined: Fri Jun 18, 2004 4:13 pm
Location: Germany
Contact:

Post by Holger » Tue Jun 20, 2006 9:53 pm

Another thing I just wanted to comment on:

>> If they're not used, then why are they there?
> dark corners after 10 years of development (or may be for the future?)

Yeah, absolutely! There are quite some more of such "dark corners" which I already wanted to clean up long ago (like a few leftover German function names etc.)... :-o

HerzAusGold
Posts: 322
Joined: Sun Sep 25, 2005 4:41 pm
Location: Germany

Post by HerzAusGold » Wed Jun 21, 2006 9:22 pm

And for all who want to see the crazy "Duff's Device" look here:

"http://en.wikipedia.org/wiki/Duff's_device"

A strange CE? Create a black hole...
And the answer is ... 42 !

Post Reply