[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Re: Inline vs. ? : operator

From: David Brown
Subject: Re: [avr-gcc-list] Re: Inline vs. ? : operator
Date: Sun, 28 Mar 2010 00:33:50 +0100
User-agent: Thunderbird (Windows/20100228)

(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
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.



Also calling a function like this:
static inline void t_BWd(char bit)
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 <address@hidden> wrote:
Joerg Wunsch wrote:
David Brown <address@hidden> 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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]