Re: [avr-gcc-list] avr-g++ local variable constructor / block body / destructor execution order

2007-09-06 Thread David Brown

Oleksandr Redchuk wrote:

2007/9/2, David Brown [EMAIL PROTECTED]:


Similarly, if you have multiple objects being constructed or
destructed, their ordering is *not* guaranteed by the compiler

AFAIR, this order guaranteed for objects in block of code and for
objects in file - in order of definitions, but not guaranteed for
objects in different files because of dependence form object files
linking order.


You are correct in thinking about the *logical* ordering - the compiler 
must generate code that runs *as though* objects were constructed in 
this order.  But it is important to remember that as long as the 
compiler knows (according to the rules of the language, and what you 
have told it in the program) it is safe to do so, it can re-order any 
calculations and statements if that lets it generate better (smaller and 
faster) code.  Ultimately, the compiler can generate any code in any 
order, as long as the view through the program's external connections 
(its volatiles, and its external library calls) is as specified by the 
programmer.



In any case this is not a question of constructor/destructor order or
even it's presence:
class iii {
public:
iii(int _i) : i(_i) {}
~iii() {}
operator int() { return i; }
private:
int i;
};

int foo(int i) {
iii a(5);
return a + i;
}

a even not be created, and this is good optimizer behavior :-)



Exactly.  Having the crit_sect volatile ensures that it is created and 
destroyed, unlike a above, but there is nothing to say that other 
non-volatile code cannot be moved back and forth over the volatile code.



are guaranteed is that the code will act as though they followed the
order given, based on what the compiler knows of the code.


I'm shure that compiler can change execution sequence of independent
lines of code and can't change that sequence for volatile objects
access.
But I'm not shure, that it can change order of non-volatile and
volatile objects access.


I believe it can (it certainly *does* do such moves here!).  Obviously 
it is only legal if such moves do not affect the volatile accesses 
themselves.  Perhaps someone here who has a better knowledge of the 
standards could enlighten us, or we could pose the question on 
comp.lang.c or comp.lang.c++, as I am by no means sure about this.



avr-gcc optimizer behavior looks reasonable, but is the C++ standard
grant this changing? I not found such grants in standard text...



inline uint32_t get_counter() {
crit_sect cs;
uint32_t x = counter;
asm volatile( : : : memory);
return x;
}

Thanks.
Yes, I think, that qualifying counter as volatile is the best solution
- it is really modifiable in interrupt :-)


Making counter volatile is certainly the traditional solution.  But 
volatile is an all-or-nothing approach - there are times when you want 
finer-grained control to get optimised code while still having the data 
accesses you need.  Memory blocks like this can help there, and C++ can 
let you hide things nicely within classes (for example, giving you 
something that has volatile write semantics, but non-volatile read 
semantics - or which has enforced atomic access like this).  I'm still 
playing around with C++ for this sort of thing - I haven't tried it in a 
real project as yet.


mvh.,

David



But in real world get_counter() is part of external code wich I
don't want to change. However, crit_sect definition is a part of
target-specific include-file for the external code and I add asm
volatile( : : : memory); to constructor and destructor of
crit_sect.





___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] avr-g++ local variable constructor / block body/ destructor execution order

2007-09-06 Thread Graham Davies

David Brown wrote:
I believe [the compiler] can [change order of ... volatile objects 
access].
Obviously it is only legal if such moves do not affect the volatile 
accesses themselves.  Perhaps someone here who has a better knowledge of 
the standards ...


I wouldn't claim better knowledge, but this is a sore spot for me so I'm 
going to chime in anyway.


I think that the compiler is not permitted to change the order in which 
volatile objects are accessed.  This would undermine the intent of volatile, 
which is to give the user exactly what he asks for.  My impression is that 
the C language is defined in terms of the behavior of an abstract machine, 
which lacks all optimization and operates in a very simplistic but 
easy-to-describe manner.  An actual compiler is allowed to deviate from 
this, in order to perform optimization, on condition that the resulting 
behavior is indistinguishable from the abstract machine at certain places 
called sequence points.  In addition, when manipulating volatile objects, it 
is not allowed to deviate at all from the abstract machine.


Graham.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] avr-g++ local variable constructor / block body/destructor ex

2007-09-06 Thread Dave Hansen




From: Graham Davies [EMAIL PROTECTED]


David Brown wrote:
I believe [the compiler] can [change order of ... volatile objects 
access].
Obviously it is only legal if such moves do not affect the volatile 
accesses themselves.  Perhaps someone here who has a better knowledge of 
the standards ...


I wouldn't claim better knowledge, but this is a sore spot for me so I'm 
going to chime in anyway.


I think that the compiler is not permitted to change the order in which 
volatile objects are accessed.  This would undermine the intent of 
volatile, which is to give the user exactly what he asks for.  My 
impression is that the C language is defined in terms of the behavior of an 
abstract machine, which lacks all optimization and operates in a very 
simplistic but easy-to-describe manner.  An actual compiler is allowed to 
deviate from this, in order to perform optimization, on condition that the 
resulting behavior is indistinguishable from the abstract machine at 
certain places called sequence points.  In addition, when manipulating 
volatile objects, it is not allowed to deviate at all from the abstract 
machine.




This is all true, but I think the key is that the volatile qualifier only 
affects what it qualifies.  For example, given the following code


  x = 1;
  y = 2;
  x = 3;
  y = 4;

If none of the variables is volatile, only the last three lines need 
generate any code, and they may be reordered any way the compiler likes.


If both variables ar volatile, each line must be executed in exactly the 
order shown.


If only x is volatile, the generated code must write a 1 to x, then a 3.  
The write of 2 to y can be elided, and the write of 4 to y can occur before, 
between, or after the writes to x.


As long as the final result is as-if the code had been performed by the 
abstract machine, and any volatile value is handled exactly as the abstract 
machine would have.


HTH,

  -=Dave

_
Test your celebrity IQ.  Play Red Carpet Reveal and earn great prizes! 
http://club.live.com/red_carpet_reveal.aspx?icid=redcarpet_hotmailtextlink2




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list