In C, is it possible to print (at compile time) the contents of a statically defined array if the inclusion of various array elements is determined by #define
values?
I have seen many questions about #pragma message
(seems helpful) but none about how to do what I am trying to do (though I may be searching for the wrong thing).
Here is what I am trying to accomplish:
I am working with a large 3rd party open source library that (among other things) includes a large array of information for which the contents of the array never change and the length of the array is determined by whether or not (tons and tons of) preprocessor symbols are defined. I need to be able to print AT COMPILE TIME what the array contains.
Here is a very small program to show the gist of what I am getting at:
#include "stdlib.h"
#include "stdio.h"
// there are tons of these, some of which are conditionally defined based on tons of other defines.
// All are defined in other header files and none are defined via the command line, i.e. via `-DTHREE`.
#define ONE
#define TWO
// ...
int main()
{
int values[] = {
#ifdef ONE
1,
#endif
#ifdef TWO
2,
#endif
#ifdef THREE
3,
#endif
#ifdef FOUR
4,
#endif
#ifdef FIVE
5,
#endif
0
};
int i = 0;
for (i = 0; values[i] != 0; i++)
{
printf("values[%d] = %d\n", i, values[i]);
}
return 0;
}
Obviously, if I compile this code (with gcc
) and run it then I get the output:
values[0] = 1
values[1] = 3
However, what I want to know is that the values 1 and 3 are present in the array at compile time. To be clear, I do not care if any particular value is or is not in the array; I only want to know what is actually in the array without having to run the binary. Ideally, my workflow would be to compile the code and search the output for specially formatted messages that would tell me what the array contains. The code should always compile as my intent is that the added diagnostics will tell me about the binary not prevent it from compiling if it does or does not include something.
I have tried to do the following:
#pragma message
. So something like: // ...
#ifdef ONE
#pragma message "1 is included"
1,
#endif
// ...
This causes compile errors (error: expected expression before '#pragma'
)
#warning
. So something like: // ...
#ifdef ONE
#warning "1 is included"
1,
#endif
// ...
This works very well but as soon as I use -Werror
(which I need to do) compilation fails.
Any thoughts on how to accomplish this would be great.
UPDATE/CLARIFICATION: in my simple example, the #ifdef
guards around each element's inclusion are just checking a single symbol. This is not reflective of the actual code; the actual code's preprocessor guards check many, many, many symbols to determine if a single array element should be included or not. As such, it is not practical for me to check a list of symbols to determine what is in the list as I would actually have to duplicate the complex preprocessor symbol checks.
I had to "get something working" so I ended up doing the following:
I wrote a python script that would parse the file containing the giant array with the #if defined(...)
logic in it and generate an identically structured block of #ifdef
code that instead of defining array elements would use #pragma message
to output information about the element that is being included in the array.
This generated preprocessor logging was then added to the source file in question above the array definition with a VERY conspicuous comment about what it is and how to regenerate it in the event that the array definition ever changed.
Ideally, I would integrate the python script into my build system so that the logging code would be automatically regenerated so that it would never get out of sync with the array definition.