1
\$\begingroup\$

When I try to compile some code with macro definition at the following definition

# define _SPEED_FACTOR0 0.9 //or any float value

I get the error

floating constant in preprocessor expression

I am using avr-gcc (version 4.8.2)

here is the full compilation command and the error

avr-gcc -g -Os -mmcu=atmega644p -c test_sens_mot.c ../utils/sources/*.c -I../utils/includes

In file included from ../utils/sources/motors.c:1:0:

../utils/sources/motors.c: In function ‘go’:

../utils/includes/global.h:14:25: error: floating constant in preprocessor expression # define _SPEED_FACTOR0 0.9 //only on timer 0

I am interested in avoiding this, and still using macros and float values.

thanks!

\$\endgroup\$
  • \$\begingroup\$ From what I can tell, the C pre-processor doesn't support (nor is required to AFAIK) floating point expressions. Related StackOverflow question \$\endgroup\$ – Tom Carpenter Apr 3 '16 at 23:27
  • 1
    \$\begingroup\$ @TomCarpenter: The C preprocessor #define statement isn't required to support arithmetic at all -- it's supposed to be strictly a text substitution mechanism. Any semantics are determined by where the macro is actually used. If it is used in a subsequent #if statement or something, THAT's where the error is occurring. \$\endgroup\$ – Dave Tweed Apr 4 '16 at 0:32
  • \$\begingroup\$ Doubt it's THAT line... probably something previous to this that isn't terminated properly. As @DaveTweed mentioned, #define statements are simple substitutions, no processing is ever done UNTIL it's substituted in... and the error on the #define line implies something's being 'done'... look above it at the previous lines. \$\endgroup\$ – lornix Apr 4 '16 at 4:35
4
\$\begingroup\$

I got it!

As Dave Tweed suggested in a comment, the issue was not the declaration itself but the way I was using that macro. In other lines I was doing this:

#if SPEED_FACTOR != 1

and if I comment this part everything works fine.

Thanks!

\$\endgroup\$
1
\$\begingroup\$

The problem is likely that you don't have any floating point library linked to the project to begin with.

This is normal for any microcontroller application, since it doesn't make a whole lot of sense to use floating point numbers there. Particularly when the MCU has no built-in FPU. Because if it doesn't, you will get floating point handling through software, which is very slow.

Therefore, when doing embedded programming, you always avoid floating point arithmetic for as long as possible.

It is a common misunderstanding among PC programmers that floating point means: "I need to display a decimal comma". That's just nonsense, you can perform all calculations on plain integers and then only calculate and print the comma position when you need to present the value to a user. Floating point numbers will just cause problems (such as floating point inaccuracy causing problems during comparison).

For example, if your program needs to display volts, with 3 decimals of millivolts, you should not create a float volt = 1.234f; variable, but rather a uint32_t milli_volt = 1234; and then do all calculations on millivolts.

Floating point rather means: "I need to do advanced math." As a rule of thumb, you should not use floating point numbers unless your program needs to do advanced math such as trigonometry. In which case you should pick a MCU with built-in FPU.


That being said, you can still calculate numeric constants in the pre-processor, without actually involving any float calculations in your code. Example:

#define CURRENT 0.20
#define RESISTANCE 47.0
#define VOLTAGE (uint32_t) (CURRENT * RESISTANCE)

Here the floating point calculation will be performed by your programming PC and not the microcontroller. The above is equivalent to writing

#define VOLTAGE 9
\$\endgroup\$
  • \$\begingroup\$ None of this explains the preprocessor error that the OP is getting. \$\endgroup\$ – Dave Tweed Apr 4 '16 at 12:20
  • \$\begingroup\$ @DaveTweed How about the first line? "The problem is likely that you don't have any floating point library linked to the project to begin with." And then the root of the problem is likely that they are using floating point where there is no need for it. \$\endgroup\$ – Lundin Apr 4 '16 at 12:22
  • \$\begingroup\$ That would result in a linker error -- a completely different message from the one he's actually getting. Also, your sweeping statements about the use of floating point arithmetic are misleading at best. Sometimes an embedded application DOES need to do "advanced math", but at a slow speed, in which case, a software FP library is completely appropriate. The decision isn't based on the kind of math that needs to be done, but rather the data representation that needs to be used. Sometimes the dynamic range of the data requires a floating-point representation. \$\endgroup\$ – Dave Tweed Apr 4 '16 at 12:26
  • \$\begingroup\$ @DaveTweed It is based on the kind of math you need to use, namely if you need to use standard lib math.h or not. \$\endgroup\$ – Lundin Apr 4 '16 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.