main.cpp :
#include "timer.hpp"
int main() {
TCC_TIMER<0> speed_timer;
TC_TIMER<3, TIMER_16BIT> update_timer;
speed_timer = TCC_TIMER<0>::Instance();
update_timer = TC_TIMER<3, TIMER_16BIT>::Instance();
for(;;);
}
timer.hpp :
#ifndef TIMER_HPP
#define TIMER_HPP
class TIMER_GENERAL {
protected:
TIMER_GENERAL() : initialized(false) {};
~TIMER_GENERAL() {};
inline void Init(int number) {
timer_number = number;
initialized = true;
}
inline bool Initialized(void) {
return initialized;
}
bool initialized;
int timer_number;
};
class TIMER_16BIT : public TIMER_GENERAL {
protected:
};
template <class T>
class TIMER_TC : public T {
protected:
};
class TIMER_TCC : public TIMER_GENERAL {
public:
};
template <int number, class T>
class TC_TIMER : public TIMER_TC<T> {
public:
static TC_TIMER<number, T>& Instance(void) {
static TC_TIMER<number, T> timer;
if(!timer.initialized) {
timer.Init(number);
}
return timer;
}
};
template <int number>
class TCC_TIMER : public TIMER_TCC {
public:
static TCC_TIMER<number>& Instance(void) {
static TCC_TIMER<number> timer;
if(!timer.initialized) {
timer.Init(number);
}
return timer;
}
};
#endif /* TIMER_HPP */
When I compile this code with g++ 7.5.0:
g++ -O3 -Wall -std=c++17 main.cpp
I get a warning in the TCC_TIMER
class:
dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]: if(!timer.initialized) {
In TC_TIMER
however, I do exactly the same and get no warning.
If I deliberately introduce an error by inserting:
timer = timer + 1;
just before the line with the warning, I get the error:
no match for 'operator+' (operand types are 'TCC_TIMER<0>' and 'int')
which indicates that the compiler knows that timer has the type TCC_TIMER<0>
.
Also, when I explicitly cast timer to TCC_TIMER<0>
:
if(!static_cast<TCC_TIMER<0>>(timer).initialized) {
the compiler is happy and the warning disappears.
If I use a function instead:
if(!timer.Initialized()) {
everything is ok too.
Can anyone explain why I get this warning in the TCC_TIMER
class and not in the TC_TIMER
class?
Can anyone explain why I do get this warning while the timer type seems to be ok?