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

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

[avr-gcc-list] avr-g++ local variable constructor / block body / destruc


From: Oleksandr Redchuk
Subject: [avr-gcc-list] avr-g++ local variable constructor / block body / destructor execution order
Date: Fri, 31 Aug 2007 17:27:50 +0300

Is this "overoptimization" bug or not?

---------------------------------
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

class crit_sect
{
public:
    crit_sect() : _sreg( SREG ) { cli(); }
    ~crit_sect() { SREG = _sreg; }
private:
    uint8_t _sreg;
};


uint32_t counter;

inline uint32_t get_counter() { crit_sect cs; return counter; }

uint16_t get_cnt_low() {  return (uint16_t)get_counter(); }

uint32_t get_delta(uint32_t start) { return get_counter() - start; }
---------------------------------

gcc 4.1.2 (WinAVR-20070525) and 4.2.0 both produces code like this:

---------------------------------
_Z11get_cnt_lowv:
        in r24,95-0x20
        cli
        out 95-0x20,r24
        lds r24,counter
        lds r25,(counter)+1
        ret
---------------------------------

~crit_sect() executed *before* counter reading in both get_cnt_low()
and get_delta()
(full listings attached).
Optimization level does'nt matter. -Os, -O1..-O3

gcc 3.4.6 produces not so "efficient" code but with right sequence -

crit_sect constructor
counter reading
crit_sect destructor
read value utilization


With
    volatile uint32_t counter;
gcc 4.x produces expected code, but, I think, "volatile" is not
required in this code.

destructor *must* be executed at end of block,
*after* variable reading, either volatile variable or not.

-- 
wbr,
ReAl

Attachment: test.cpp
Description: Binary data

Attachment: test-3.4.6.s
Description: Binary data

Attachment: test-4.1.2.s
Description: Binary data


reply via email to

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