I am thinking about the following problem: I want to program a microcontroller (let's say an AVR mega type) with a program that uses some sort of look-up tables.
The first attempt would be to locate the table in a separate file and create it using any other scripting language/program/.... In this case there is quite some effort in creating the necessary source files for C.
My thought was now to use the preprocessor and compiler to handle things. I tried to implement this with a table of sine values (just as an example):
#include <avr/io.h>
#include <math.h>
#define S1(i,n) ((uint8_t) sin(M_PI*(i)/n*255))
#define S4(i,n) S1(i,n), S1(i+1,n), S1(i+2,n), S1(i+3,n)
uint8_t lut[] = {S4(0,4)};
void main()
{
uint8_t val, i;
for(i=0; i<4; i++)
{
val = lut[i];
}
}
If I compile this code I get warnings about the sin
function. Further in the assembly there is nothing in the section .data
. If I just remove the sin
in the third line I get the data in the assembly. Clearly all information are available at compile time.
Can you tell me if there is a way to achieve what I intent: The compiler calculates as many values as offline possible? Or is the best way to go using an external script/program/... to calculate the table entries and add these to a separate file that will just be #include
d?
constexpr
as a hint to the compiler to execute a function at compile-time. – Standfastconstexpr
is no advantage. It merely allows an expression being evaluated at compile time (and even forcing the compiler to to it, e.g. by assigning to an enumeration doesn't prevent it from re-evaluating at runtime at a different location in the same source file!). It does not enforce or hint anything. That said, my GCC optimizes the code snippet in the OP just fine into a compiletime-evaluated lookup table (without any particular special dance). – Bautzensin
will become an error if you use-fno-builtin
which is becausegcc
is currently treating most math functions as constant expressions if it uses the builtin version. – Twinsin
will only return-1
/255
,0
or1
. Maybe you will use ` ((uint8_t) (sin(M_PI*(i)/n)+1)/2*255)` – Chesnut