Sameh NAGI Sameh NAGI - 10 days ago 5
C Question

How macros in embedded C affect memory?

I know that macros in C such as:

#define VARNULL (u8)0


doesn't store this
VARNULL
in RAM, but this of course will increase the code size in the FLASH.

But what if I have a multi-line macro such as:

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0)


By knowing that
func1
,
func2
, and
func3
are functions from different
.c
files. Does this means that these functions will be stored in RAM? And of course in the FLASH (the code).

Kindly correct me if I'm wrong?

Answer

Macros, and any other directive prefixed with a # are processed before C compilation by the pre-processor; they do not generate any code, but rather generate source code that is then processed by the compiler as if you had typed in the code directly. So in your example the code:

int main()
{
    CALL_FUNCS(2) ;
}

Results in the following generated source code:

int main()
{
    do { \
      func1(2);
      func2(2);
      func3(2);
    } while (0) ;
}

Simple as that. If you never invoke the macro, it will generate exactly no code. If you invoke it multiple times, it will generate code multiple times. There is nothing clever going on the macro is merely a textual replacement generated before compilation; what the compiler does with that depends entirely on what the macro expands to and not the fact that it is a macro - the compiler sees only the generated code, not the macro definition.

With respect to const vs #define, a literal constant macro is also jyst a textual replacement and will be placed in the code as a literal constant. A const on the other hand is a variable. The compiler may simply insert a literal constant where that generates less code that fetching the constant from memory, in C++ that is guaranteed for simple types, and it would be unusual for a C compiler not to behave in the same way. However, because it is a variable you can take it's address - if your code does take the address of a const, then the const will necessarily have storage. Whether that storage is in RAM or ROM depends on your compiler and linker configuration - you should consult the toolchain documentation to see how it handles const storage.

One benefit of using a const is that const variables have strong typing and scope unlike macros.

Comments