Search code examples
cgccc-preprocessorpreprocessor-directive

Determine the expansion of a C macro


Is there a way to determine the "final value" of a expanded C macro by inspecting the compiled object or by running some form of gcc -E on the .c or .h file?

test.h

#define AAA 1
#define BBB 10
#define CCC (AAA+BBB)

test.c

#include <stdio.h>
#include "test.h"

int main(){
   printf("%d\n", CCC);
   return 0;
}

Thus is there someway to get the expanded value either:

#define CCC 11

or

#define CCC (1+10)

If compiled with

gcc -dM -E test.c | grep CCC 

or

gcc -dD -E test.c | grep CCC

outputs

#define CCC (AAA+BBB)

which requires me to still know what AAA and BBB are.

Compiled with:

gcc -E test.c

Gives (skipping the boilerplate):

# 4 "test.c"
int main(){
printf("%d\n", (1+10));
return 0;
}   

While its expanded CCC I've now lost the mapping back to CCC.

Edit: As it was unclear, what i'd like is someway to determine what CCC is (either 11 or 1+10 (as the gcc -E example showed it only inserted (1+10) not 11), preferably without altering the code itself. Printf was a bad idea to use in the MRE, what i actually had in mind was code like:

struct my_struct {
    int my_array[CCC]
    ... other stuff ...
}

The question is how big is my_array, so i can make a struct in another language (python via ctypes) and know how much space i need. I know for structs i can use pahole but was hoping to do this with only gcc and in the more general case (say a global array not in a struct).


Solution

  • At no point will the preprocessor ever create

    #define CCC (1+10)
    

    The expansion of CCC is always (AAA+BBB); it's just that the result of macro expansion is rescanned for more macros to expand, at which point AAA and BBB turn into 1 and 10, respectively.

    Perhaps a clearer example of this is

    #define AAA 1
    #define CCC AAA
    #define AAA "hello"
    
    size_t x = sizeof CCC;
    

    This code will expand to "hello", not 1. CCC always has a value of AAA; it's just that by the time size_t x = sizeof CCC; is processed, AAA itself will turn into "hello".

    This example also demonstrates that macros can be redefined, so there may not even be a single answer to "what is the value of CCC?".

    That's why there's no simple compiler invocation or switch; what you want simply doesn't exist.

    That said, if you can use custom code, you can just run e.g.

    #define AAA 1
    #define BBB 10
    #define CCC (AAA+BBB)
    CCC
    

    through gcc -P -E and the result will be just (1+10).