This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Passing a float by value or reference

Hi,

We are seeing some strange stuff when trying to pass floating point values to a function. When we pass the parameter by value (meaning as an actual floating point number) the parameters' value changes. When we debug the code we can see that in the disassembly there is a call too __aeabi_f2d. However there should be no reason to call this since all of the values are floats and not doubles. When we pass the floating point number by reference everything works fine.

We are using the nRF52840 with the gcc compiler that comes with the 4.20a version of segger embedded studio.

Meaning this does not work, the value of variable intermediate is not the same value as the value found in input_param :

  float32_t intermediate = *pIncomingSample;
  turn_gyry(intermediate);

void turn_gyry(float32_t input_raw){
  float32_t output_low_pass; 
  float32_t output_moving_average;
  float32_t output_derivative;
  float32_t input_param = input_raw;

  filter_turn_gyry_low_pass(&input_param, &output_low_pass);
  filter_turn_gyry_moving_average(&output_low_pass, &output_moving_average);
  filter_turn_gyry_derivative(&output_moving_average, &output_derivative);

  printf("output low pass %f", output_low_pass );
  printf("output derivative %f", output_derivative);
}

But this works just fine:

  float32_t intermediate = *pIncomingSample;
  turn_gyry(pIncomingSample);

//the function definition of turn_gyry
void turn_gyry(float32_t *input_raw){
  float32_t output_low_pass; 
  float32_t output_moving_average;
  float32_t output_derivative;
  float32_t input_param = input_raw;

  filter_turn_gyry_low_pass(&input_param, &output_low_pass);
  filter_turn_gyry_moving_average(&output_low_pass, &output_moving_average);
  filter_turn_gyry_derivative(&output_moving_average, &output_derivative);

  printf("output low pass %f", output_low_pass );
  printf("output derivative %f", output_derivative);
}

Does anybody have an explanation for this behavior? I believe that the call to __aeabi_f2d implies that for some reason the compiler thinks he needs to convert a float to a double but there is no reason to do this...

Any ideas are welcome

Thanks!

Parents
  • When we debug the code we can see that in the disassembly there is a call too __aeabi_f2d

    Those are required for those floating point printf() arguments. Floating porint variable arguments are always (and implicitly) converted to double.

    Ifn case these printfs() are only there for debugging, consider looking at how the NRF_LOG_FLOAT() macros work for displaying a floating point number using just integer arguments.

  • Thanks for joining in.

    I tried removing all the printfs and removed the support for floats in printfs in the compiler options. The disassembly still shows the aeabi_f2d. Also when stepping through the code we can see that the conversion is being called in the function call to "turn_gyry(*pIncomingSample) in which is cleary defined that this should be a float32_t. So it's not clear to me, even with the printfs, why the compiler would try to make a conversion here.

Reply
  • Thanks for joining in.

    I tried removing all the printfs and removed the support for floats in printfs in the compiler options. The disassembly still shows the aeabi_f2d. Also when stepping through the code we can see that the conversion is being called in the function call to "turn_gyry(*pIncomingSample) in which is cleary defined that this should be a float32_t. So it's not clear to me, even with the printfs, why the compiler would try to make a conversion here.

Children
No Data
Related