(Try to reply to the list, rather than individual posters - that way
everyone gets to see your posts and learn from them or comment on them.
Besides, I'm off on holiday tomorrow - if you ask me more questions,
you'll have to wait a couple of weeks for the answer!)
Szikra Istvan wrote:
You might be right about the ?: operator, but it does not explain everything.
I'm not sure if ?: should return a value or not on it's own (since as
I said I'm no expert in C), it sure can be used as a right value in an
assignment.
It all would be ok, if for example the code said
a= bit_write(PORTA,b,c);
or the function had a
return bit_write(PORTA,b,c);
statement. But it does not.
You are still asking the compiler to calculate the answer - you are then
ignoring it. If there was no volatile involved, the compiler could see
that the value is ignored and can therefore remove the calculation. But
since you are using a volatile, it must obey the rules of C and do the
calculation - including the "extra" read of PORTA - and then just not
store the result anywhere.
It's worth noting that in C, the meaning of the right hand side of an
assignment expression is considered independently of the left hand side.
For example, if you add two 32-bit longs and assign the answer to an
8-bit variable, the compiler must still consider the full 32-bit
calculation even though 24 of the bits will be thrown out. Then, if the
optimiser is able to prove it's safe, it can reduce the generated code.
But if "volatile" blocks the optimisations, it must do the full
calculation.
My other problem with this is, it only "returns a value" when it's
executed indirectly (contained in a function, that provides it's c
parameter as a variable!). For example it does not generate an 'in'
instruction in the main program (function). If you were right about
that ?: should read the volatile twice, then it should happen at the
first bit_write() statement in the main function too.
I didn't notice this earlier. But this behaviour, I believe, is the
erroneous behaviour.
It would seem that this situation is not entirely clear - the compiler
should at least be consistent. But it's not obvious what the correct
behaviour should be. Note that we are concerned here about getting
/correct/ code - not necessarily the smallest and fastest code.
Perhaps some of those more familiar with the internals of gcc and/or the
C standards may like to comment. Otherwise, I'd recommend avoiding the
?: operator with volatiles - stick to code that you know works correctly
and optimally.
mvh.,
David
Also calling a function like this:
static inline void t_BWd(char bit)
{
bit_write(PORTA,bit,0);
}
only generates a 'cbi' but no 'in' instruction.
So something is not right either way.
On Sat, Mar 27, 2010 at 10:02 PM, David Brown <david.br...@hesbynett.no> wrote:
Joerg Wunsch wrote:
David Brown <david.br...@hesbynett.no> wrote:
Evaluating the result of "p |= BIT(b)" means carrying out the
or-assign, then reading the value of p and returning it.
You're right, I stand corrected.
That's certainly how /I/ interpret the way volatile works in such cases. I
believe there is some uncertainty about how it should work in C++ - the same
statement /may/ have a different interpretation in C and C++ when volatiles
are sort-of read in this way.
All in all, the fact that even experts are not always accurate in such cases
suggests that you should stay well away from such code - an explicit "if" is
clear, works exactly as intended, and in some cases gives noticeably better
code than a logically equivalent "?:" expression.
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list