nholthaus / units

a compile-time, header-only, dimensional analysis and unit conversion library built on c++14 with no dependencies.
http://nholthaus.github.io/units/
MIT License
961 stars 137 forks source link

volatile operators #184

Closed Guillaume227 closed 5 years ago

Guillaume227 commented 6 years ago

I would like to start using this (very cool) library in an embedded context (stm32 with gcc toolchain). I have started strong-typing former floats variables with e.g. units::temperature::celsius_t. However I am running into trouble with volatile float variables: suddenly all of the standard operators like <, > == etc. are causing compilation to fail because of missing volatile overloads. It feels like a lot of boiler-plate to have to define all the combinations explicitly.

Does anyone have a similar experience or any suggestion?

nholthaus commented 6 years ago

I think you're the first. A lot of use of volatile in embedded is cargo-cult programming, and most of our embedded users have some means of ensuring synchronization. Personally I've never needed the keyword myself (although I've done a lot of real-time embedded), so I'll have to do a bit of research to make sure what we're doing is safe for volatile variables, or make it so.

Guillaume227 commented 6 years ago

[I mis-clicked on 'Close and comment' instead of just 'comment' so now it looks like I closed and reopened the issue - sorry about the noise]

I might be perpetuating the cult, so here is a bit of background on my use case: I am migrating a C code base to c++ (one of the selling points in the ability to use the units library).

Basic code pattern:

// in temp_control.c
static volatile float m_temp_measure;
static float temp_limit;

void interrupt_method(){
    m_temp_measure = READ_TEMP_FROM_ADC();
}

void thread_routine(){
  for(;;){
       if(m_temp_measure >= temp_limit)
           TURN_ON_LED();
       else
           TURN_OFF_LED();
      sleep_some();
  }
}

I would like variable types to be (using float underlying type, that's working fine):

namespace temp_control{
   using namespace units::temperature;
    volatile celsius_t m_temp_measure;
    celsius_t temp_limit;

   // rest of the code
}
GElliott commented 6 years ago

That pattern is fine for single-threaded code, but I think you might be better served by std::atomic (at least on modern-ish CPUs). It appears to work today:

std::atomic<meter_t> m;
EXPECT_TRUE(m.is_lock_free());