samedi 31 août 2019

Compile time calculation of constants fails, some const not yet initialized

I want to initialize a constant struct with using a function at compile time. All the inputs for this function are constants so it should theoretically be possible. but some const values used by the function are seemingly not yet initialized by the compiler, leading to an incorrect value.

timer_setup.c:

const int TIMER_PRESCALER_1_2    = 1;

timer_setup.h:

extern const int TIMER_PRESCALER_1_2;

(I don't see extern "C" in the header file of this library)

abstraction_layer.cpp

typedef struct
{
  uint16_t value;
  //const int *option;
  int option;
  uint64_t div_min;
  uint64_t div_max;//value*65536 but potentially higher with post divider
  uint8_t shift;
}
prescaler_t;

#define PRESCALER_DEF(p,s) {p,TIMER_PRESCALER_1_##p,p*1,65536ULL*p,s}

#if defined(_SAM3XA_)

static const prescaler_t prescalers[] = {
  PRESCALER_DEF(2,1),
  PRESCALER_DEF(8,3),
  PRESCALER_DEF(32,5),
  PRESCALER_DEF(128,7),
};

#else

static const prescaler_t prescalers[] = {
  PRESCALER_DEF(1,0),
  PRESCALER_DEF(8,3),
  PRESCALER_DEF(64,6),
  PRESCALER_DEF(256,8),
  PRESCALER_DEF(1024,10)
};
#endif

[...]

timer_divider_settings_t timer_divider_settings_calc(double frequency_hz,double period_s)
{
  int8_t index;
  uint64_t divider_min_1;
  uint64_t total_divider;
  timer_divider_settings_t settings;

  total_divider = total_divider_calc(frequency_hz,period_s);  

  index = prescaler_index_find(total_divider);

  settings.option = prescalers[index].option;
  settings.divider_min_1 = (total_divider >> prescalers[index].shift) -1;

  return settings;
}

static const timer_divider_settings_t BIT_PERIOD_S          = timer_divider_settings_calc(0,LN_BIT_PERIOD_S);

This constant is not correct.

I expect the value to be the same regardless whether it is calculated at compile time or run-time. I expect it to be the same regardless of the target platform.

The constant is incorrect if I compile it for Arduino Due target, the AVR boards do not have this issue. If I initialize the constant at run-time in a function it works, but I want them filescope and const. One thing that does work is to use a pointer in the struct in stead of copying the value, but I do not want that work around.

Aucun commentaire:

Enregistrer un commentaire