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!
2 Answers 2
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!
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
-
\$\begingroup\$ None of this explains the preprocessor error that the OP is getting. \$\endgroup\$Dave Tweed– Dave Tweed2016年04月04日 12:20:44 +00:00Commented Apr 4, 2016 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– Lundin2016年04月04日 12:22:32 +00:00Commented Apr 4, 2016 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– Dave Tweed2016年04月04日 12:26:36 +00:00Commented Apr 4, 2016 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– Lundin2016年04月04日 12:31:24 +00:00Commented Apr 4, 2016 at 12:31
#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\$