[EMAIL PROTECTED] wrote:
- no optimizations (-O0), default debugging info (-g).

After changing code to read k, I get the same result.

UInt16 g_Stuff = 10;

UInt32 PilotMain (UInt16 cmd, void *cmdPBP, UInt16 launchFlags)
{

static UInt16 k = 0;

UInt16 j = 0;
k = k + 1;
j = k + 2;
return errNone;
}

I would think turning off optimizations would take care of this.
BUT, I would like to point out that just adding "j = k + 2;" will
not cause the compiler to compute the value of k.  Why?  Because
just like the compiler knew the k's value wasn't read, it knows
that j's value wasn't read either.  Therefore, it knows that it
doesn't need to compute j, which means it doesn't need to read k,
which means it *still* believes that k isn't read.  So, adding
"j = k + 2;" makes no difference either way, probably.

And yes, I have actually run into a situation where I tried to
add a simple statement like that to force the compiler to compute
something, and the compiler was too smart for me.  I ended up
using some mathematical property that the compiler couldn't know
about to trick it into thinking some value was needed.

For example, in your case you could do this:

        UInt16 j = 0;
        k = k + 1;
        j = (k % 2) * ((k + 1) % 2);
        return (j + errNone);

That expression will always come out to zero (since either k%2 or
(k+1)%2 is zero), but the compiler won't be sophisticated enough
to know that.  But, it does need to compute a proper return value,
so it belives j is needed, which makes it believe k is needed.

Another possible idea, which I have not tried, is to create a
dummy global variable, and modify it based on the value of k.
Since the compiler builds each translation unit separately,
it cannot know whether some other object file has code that
reads the global variable or not, so it has to assume it matters
and shouldn't be able to optimize away things that modify the
global variable.  So, you could do something like this:

        UInt16 g_dummy;

        UInt32 PilotMain (.......)
        {
            static UInt16 k = 0;
            k = k + 1;
            g_dummy = k;
            return errNone;
        }

However, retyping that, I just noticed one important thing:
it's possible, and even common, for code to enter PilotMain()
when globals aren't available.  This happens with a variety
of launch codes.  So, since a static local variable is essentially
a global variable (stored in the same area and everything) but
with a variable name that has a smaller lexical scope, you are
essentially declaring a global variable where it's not legal
to put one.  What kind of code can the compiler generate that
will be correct when a non-globals launch code is received?
As far as I can tell, the answer is that it can't.

You might check to see if you have any pragmas or other compiler
directives that instruct the compiler to warn on globals, because
PilotMain() really shouldn't be accessing any globals (regardless
of whether they're regular globals or the kind you're using).  I
can't say for sure what the issue is, but it seems like it might
be related to what's going on.

  - Logan

--
For information on using the PalmSource Developer Forums, or to unsubscribe, 
please see http://www.palmos.com/dev/support/forums/

Reply via email to