Reply by Paul Curtis May 12, 20082008-05-12
Hi Robert,

> > > > > Interesting. The references I was able to look up indicated
> the
> > > value of
> > > > > an assignment expression was its left hand side. I'm quite
> willing
> > > to
> > > > > believe you over them though. If anyone here is likely to know
> > > it's you.
> > > >
> > > >==> You'r both talking about the same thing:
> > > >The left hand operand IS the value of what was written!
> > > >Same thing.
> > >
> > > Unless the left hand operand is volatile.
> >
> >Can't happen. Ever. Volatile just doesn't figure in this at all, the
> fact
>
> Paul, I think you misunderstood. I was saying the interpretations are
> different if the left hand is volatile. IE The value *assigned to* the
> and the value *of* the variable are different in that case. Not that the
> value of the variable is used.

I understand. But it still can't happen, there was no request to read c in
the assignment 'c = k' *even* if it's written like this 'x = c = k'.

Let me show you a concrete example. Let's take this little snippet:

c = k;

Assuming c is volatile, would you expect c to be written and then read? I
assume *not*. You just would not expect that, would you, and do you see a
compiler that does it? No. The fact is that 'c = k' is an expression, not
a statement. It can be turned into a statement by placing it in a statement
sequence and terminating it with a semicolon. THERE IS NO ASSIGNMENT
STATEMENT. So 'c = k;' means evaluate the expression 'c = k' and throw the
result away. By your hypothetical logic, c should be read and then result
placed in the bit bucket, but it's not.

Hence, why should 'c = k' be treated differently in two contexts? It should
not! It should be consistent, and the standard guarantees that!

> I'm a little curious (only a little) how the various references I
> checked all managed to refer to using the value of the variable as the
result
> of the assignment
> - Maybe a difference between C and C++
> - an evolution of standard C
> - the people writing them are all referring to one another and
> the
> original author didn't realize there could be a difference.
> - ambiguity of the english language

I believe the problem lies in the wording of the result of the assignment.
The value yielded by the assignment statement is the stored value of c, not
the value that was assigned to to. This does not mention re-reading c.
Re-reading a volatile would be against the standard because *only* a write
is requested.

Think about it logically in the statement c = k with c volatile. You only
expect a WRITE, but c=k is an expression that yields a value that you're
throwing away. That value must still be yielded so wither (a) every c=k
would need to re-read the volatile or none of them would. I conjecture that
you would want c=k *not* to re-read c and, indeed, the standard requires it
not to be read after being written to.

Regards,

-- Paul.

An Engineer's Guide to the LPC2100 Series

Reply by Robert Adsett May 12, 20082008-05-12
At 09:24 PM 5/11/2008 +0100, Paul Curtis wrote:
>Hi,
>
> > > > Interesting. The references I was able to look up indicated the
> > value of
> > > > an assignment expression was its left hand side. I'm quite willing
> > to
> > > > believe you over them though. If anyone here is likely to know
> > it's you.
> > >
> > >==> You'r both talking about the same thing:
> > >The left hand operand IS the value of what was written!
> > >Same thing.
> >
> > Unless the left hand operand is volatile.
>
>Can't happen. Ever. Volatile just doesn't figure in this at all, the fact

Paul, I think you misunderstood. I was saying the interpretations are
different if the left hand is volatile. IE The value *assigned to* the and
the value *of* the variable are different in that case. Not that the value
of the variable is used.

I'm a little curious (only a little) how the various references I checked
all managed to refer to using the value of the variable as the result of
the assignment
- Maybe a difference between C and C++
- an evolution of standard C
- the people writing them are all referring to one another and the
original author didn't realize there could be a difference.
- ambiguity of the english language

Ah, well

Robert

"C is known as a language that gives you enough rope to shoot yourself in
the foot." -- David Brown in comp.arch.embedded
http://www.aeolusdevelopment.com/
Reply by Richard Duits May 11, 20082008-05-11
It is not the LPC code read protection that is the problem here, but the
flash magic patching the image file with the CRP value at 0x3FC (doing
this from memory, so don't shoot me if this is the wrong address).

I know this because I did run into this myself a while ago. All our hex
files don't have the CRP signature and we use the enable code read
protection option of flash magic to insert this when we are done
testing. But if you do not reserve this address in your linker file or
an fixed address variable, it can be a problem.

Regards,
Richard.
Paul Claessen wrote:
> You can do very nasty things with CRP, but I don't think overwriting one instruction in a code
> sequence is part of that ...
>
> ~ Paul Claessen
>
> ----- Original Message -----
> From: "Richard Duits"
> To:
> Sent: Sunday, May 11, 2008 7:23 AM
> Subject: Re: [lpc2000] Re: UART stuck waiting for THRE
>
>> Are you using flash magic or some other program that can automatically
>> insert a code read protection value?
>> Maybe this overwrites one critical instruction in this code sequence,
>> for example the compare/bit test.
>>
>> Regards,
>> Richard.
>> Paul Curtis wrote:
>>
>>> Hi,
>>>
>>>
>>>
>>>> The int vs. char parameter is not what fixes it. It apparently has to
>>>> do with spacing of the code from the beginning of the function. Even
>>>> with the char parameter, I added an if{ statement at the beginning of
>>>> the function which checked for '\n' and then added a '\r' if it
>>>> matched. This didn't work. So I added a couple dummy statements to
>>>> the beginning and then it worked again. Very strange.
>>>>
>>>>
>>> If it's a code placement issue, then perhaps you're suffering from MAM
>>> issues?
>>>
>>> --
>>> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
>>> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>>>
>>>
>>>
>>>
>>>
>>
>
Reply by Robert Adsett May 11, 20082008-05-11
At 09:49 PM 5/11/2008 +0000, mattwoolsey wrote:
>Using flash magic to load, but CRP is turned off.
>
>Changing from optimization Level 0 to fixes the problem.
>Or changing to MAM "disabled" works. MAM "partially enabled" did not
>help. If I have to disable the MAM, isn't that a bug in the chip if
>it won't execute code correctly?

Yep, check the errata sheet.

Robert

Another sign of the end of civilization, our technical magazines are
getting chatty
From an EETimes product descriptions 2006/08/09
".... systems that can sample gobs of inputs simultaneously"
Now just what is the technical definition for gobs again?
http://www.aeolusdevelopment.com/
Reply by mattwoolsey May 11, 20082008-05-11
Using flash magic to load, but CRP is turned off.

Changing from optimization Level 0 to fixes the problem.
Or changing to MAM "disabled" works. MAM "partially enabled" did not
help. If I have to disable the MAM, isn't that a bug in the chip if
it won't execute code correctly?

MX
--- In l..., "Charles R. Grenz"
wrote:
> Ralph Hempel wrote:
> > Paul Claessen wrote:
> >
> >> As for your, in itself valuable, suggestion to read the standard
isn't
> >> of much help here, since it
> >> states:
> >> "What constitutes an access to an object that has volatile-
qualified
> >> type is
> >> implementation-defined."
> >
> > Paul, I think that that's Paul Curtis' point exactly, and he's got
> > years of experience at a very high (low?) level with just this
kind
> > of isssue.
> >
> > Matt indicated that his problem "went away" when he used char
instead
> > of int, but then reappeared when he added some code to the
function.
> >
> > He also indicated it went away when he went back to the default
> > optimization level instead of 0, which agin reduces code size...
> >
> > Paul Curtis suggested a possible MAM issue, which is fairly easy
to
> > check out.
> >
> Hi Paul,
>
> I agree with both Paul and Ralph on the MAM issue. Have seen
this on a 2103 running thumb mode and found that just adding a NOP to
the procedure everything worked just perfectly again. I switched from
FULL ON to PARTIALLY ON and that fixed it for good. I do not see what
processor type you are running but another issue for us was the core
voltage to the processor was changed from 1.8VDC to 1.95VDC which
also allowed us to run a 60MHz PLL.
>
> regards,
> Charles
>

Reply by Paul Curtis May 11, 20082008-05-11
Hi,

> > > Interesting. The references I was able to look up indicated the
> value of
> > > an assignment expression was its left hand side. I'm quite willing
> to
> > > believe you over them though. If anyone here is likely to know
> it's you.
> >
> >==> You'r both talking about the same thing:
> >The left hand operand IS the value of what was written!
> >Same thing.
>
> Unless the left hand operand is volatile.

Can't happen. Ever. Volatile just doesn't figure in this at all, the fact
that something is volatile means that has to be assigned before a sequence
point but that does not affect the semantics of the assignment operator.

Quoting from the standard:

EXAMPLE 2. In the fragment:

char c;
int i;
long l;
l = (c = i);

the value of i is converted to the type of the assignment expression c = i,
that is, char type. The value
of the expression enclosed in parentheses is then converted to the type of
the outer assignment expression,
that is, long int type.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Reply by Paul Curtis May 11, 20082008-05-11
Hi Paul,

> To Paul Curtis:
> Were you claiming that (to simplify the case)
> return 1;
> is actually an assignment expression?
> (something I'm not buying! ;-)

Yes, it's treated as an assignment to return value of the function. It has
*all* the traits of an assignment as the r-value is converted to the return
type of the function and then assigned to the "thing" that the function
returns.

Quoting form the ISO document: "If a return statement with an expression is
executed, the value of the expression is returned to the caller as the value
of the function call expression. If the expression has a type different from
the return type of the function in which it appears, the value is converted
***as if by assignment to an object having the return type of the
function***."

My emphasis, of course.

In the many compilers I have written and maintained, return statements are
best handled by assignment to an object that denotes return value of the
function. In most C languages this just happens to be the lowest register
(R0 on ARM) so the object is just something that sits in that hard register.
Or it's a register pair for doubles. Or it's a pointer to somewhere passed
in a register for structure returns. In essence "return x" is rewritten as
"return_value = x; goto function_exit" by the compiler with return_value
designated by a hard register.

Regards,

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Reply by Paul Curtis May 11, 20082008-05-11
Hi,

> >unsigned x;
> >volatile signed char c;
> >
> >x = c = 0xff;
> >
> >What's the value of x? Hmmm. 0xff as x is unsigned or ~0U because -1
> is
> >stored in c? Or something else because c is volatile?
> >
> >Doesn't matter a damn, the ISO standard specifies what happens: the
> value
> >stored should be used which precludes re-reading c in this case.
>
> Really? Isn't there a question of order of operations here. Every
> time
> I've seen this construct (barring volatile) it is accompanied by notes
> that
> the order of operations is undefined and that x could end up with the
> either the value of c after the write or the value c had before the
> write. PC-Lint certainly complains about it.

No. Associativity of operators applies and, hence, x = c = 0xff is treated
as x = (c = 0xff) as associativity is right to left. The value of c = 0xff
is what is assigned to x. In this case, 0xff is assigned to c which is the
value 8-bit signed value -1. -1 is then converted from (signed char)-1 to
(signed int)-1 and ultimately to unsigned which yields 0xffffffffU for a
32-bit machine. Don't believe me? Go try it.

> Surely this can be implemented as
>
> x=c;
> c=0xff;
>
> which does imply a read.

That would be a broken compiler because it does not assign to c first as
required by the standard (associativity of operators). So no, it would be
quite wrong to re-write x = c = 0xff as (x = c), (c = 0xff) as reverses the
assignment order.

Regards,

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Reply by Robert Adsett May 11, 20082008-05-11
At 01:12 PM 5/11/2008 -0400, Paul Claessen wrote:

>----- Original Message -----
>From: "Robert Adsett" --- snip ---
>
> >>
> >>Quite right to object. The result of the expression is the value of what
> >>was written, nothing more, nothing less.
> >
> > Interesting. The references I was able to look up indicated the value of
> > an assignment expression was its left hand side. I'm quite willing to
> > believe you over them though. If anyone here is likely to know it's you.
>
>==> You'r both talking about the same thing:
>The left hand operand IS the value of what was written!
>Same thing.

Unless the left hand operand is volatile.

> > Every time I've seen this construct (barring volatile) it is
> accompanied by notes that
> > the order of operations is undefined
>
>==> No, the order IS defined. You're probably referring to situations were
>pre-or suffix operators
>(++,--) are involved, THEN and only THEN is the order undefined.
> > and that x could end up with the either
> > the value of c after the write or the value c had before the
> > write. PC-Lint certainly complains about it.
>
>==> No, you will NEVER end up with the value of c in x before 0xff is
>written to c.
>Again the order IS specified: x = c = 0xff is an expression and the '='
>operator has right to left
>associativity.
>No reason for PC-lint to complain about anything.

Oops, quite right. The complaint is about depending on the precedence, not
that it's undefined. My apologies.
>To Paul Curtis:
>Were you claiming that (to simplify the case)
>return 1;
>is actually an assignment expression?

Makes sense to me. How does it differ?

Robert

"C is known as a language that gives you enough rope to shoot yourself in
the foot." -- David Brown in comp.arch.embedded
http://www.aeolusdevelopment.com/
Reply by Paul Claessen May 11, 20082008-05-11
----- Original Message -----
From: "Robert Adsett"

--- snip ---

>>
>>Quite right to object. The result of the expression is the value of what
>>was written, nothing more, nothing less.
>
> Interesting. The references I was able to look up indicated the value of
> an assignment expression was its left hand side. I'm quite willing to
> believe you over them though. If anyone here is likely to know it's you.

==> You'r both talking about the same thing:
The left hand operand IS the value of what was written!
Same thing.

>>x = c = 0xff;
>>
>>What's the value of x? Hmmm. 0xff as x is unsigned or ~0U because -1 is
>>stored in c? Or something else because c is volatile?
>>
>>Doesn't matter a damn, the ISO standard specifies what happens: the value
>>stored should be used which precludes re-reading c in this case.
>
> Really? Isn't there a question of order of operations here.
==> Yes!
> Every time I've seen this construct (barring volatile) it is accompanied by notes that
> the order of operations is undefined

==> No, the order IS defined. You're probably referring to situations were pre-or suffix operators
(++,--) are involved, THEN and only THEN is the order undefined.
> and that x could end up with the either
> the value of c after the write or the value c had before the
> write. PC-Lint certainly complains about it.

==> No, you will NEVER end up with the value of c in x before 0xff is written to c.
Again the order IS specified: x = c = 0xff is an expression and the '=' operator has right to left
associativity.
No reason for PC-lint to complain about anything.
Again, it gets different when you sprinkle some ++ or -- around in such an expressions.

To Paul Curtis:
Were you claiming that (to simplify the case)
return 1;
is actually an assignment expression?
(something I'm not buying! ;-)

~ Paul