avr-gcc-list
[Top][All Lists]
Advanced

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

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


From: David Brown
Subject: Re: [avr-gcc-list] avr-g++ local variable constructor / block body / destructor execution order
Date: Thu, 06 Sep 2007 08:40:32 +0200
User-agent: Thunderbird 2.0.0.6 (Windows/20070728)

Oleksandr Redchuk wrote:
2007/9/2, David Brown <address@hidden>:

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.






reply via email to

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