Image

Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

How to partially pre-process a file, without expanding #include or #embed ?

+4
−0

I'm debugging some "clever" macros (similar to, but not exactly the same as, X macros https://software.codidact.com/posts/293492 ).

Is there a way to get a compiler or a preprocessor (such as gcc or cpp or gpp) to expand only "short" macros and leave "long" preprocessor stuff alone? so if I have something like

#include <enormous_library>
#include <some_other_library>
#embed "embedded_literals.txt"

int main(void){
    set_baud_rate(baud_rate)
}

and one of those libraries mentions

#define baud_rate 1200

I want to somehow generate a (relatively short) partially-preprocessed file something like

#include <enormous_library>
#include <some_other_library>
#embed "embedded_literals.txt"

int main(void){
    set_baud_rate(1200)
}

The

gcc -save-temps 

option tells gcc to expand all the preprocessor stuff into an enormous file with a copy of all the libraries and embedded literals, which can make what I'm looking for hard to find.

History

1 comment thread

I think you are rather looking for some way to visualize pre-processor contents but I'm not really aw... (1 comment)

1 answer

+0
−0

If your goal is just to temporarily see what a file looks like without certain headers, and the headers themselves do not depend on each other, then you can either temporarily comment them out, or declare a "guard" macro for them


Let me explain header "guards"

When creating a header file, these lines are almost always written:

#ifndef _LIB_NAME_H
#define _LIB_NAME_H



#endif /* _LIB_NAME_H */

They provide protection against including the same header twice


Example:

There is another header:

#ifndef _LIB_2_H
#define _LIB_2_H

/* some code here */
#include "lib_name.h"

#endif /* _LIB_2_H */

And in the main file we do:

#include "lib_name.h"
#include "lib_2.h"

/* ... */

If in lib_name.h we had, for example, typedef int some_t and there were no guards, then we would define the same some_t twice, which is already an error

So we check whether the macro is defined - "has this header already been included?"

If not, we provide the code and define the macro, so the next time the code will not be inserted again

This is implemented by using #ifndef directive (if not defined)


In this case, this can be used to trick headers into thinking they were already included

To do this, we need to define the macros of the headers we don't need before including them

In principle, the macro name can be anything, but a common convention is:

_HEADER_NAME_H

It starts with _, then the header name in uppercase, and at the end .h is replaced with _H (if the file has that extension)


You can define these macros either before including the unwanted headers:

#define _ENORMOUS_LIBRARY
#include <enormous_library> /* This library will be ignored */

#include <some_other_library>
#embed "embedded_literals.txt"

int main(void){
    set_baud_rate(baud_rate)
}

Or directly when running the command:

$ gcc -D_ENORMOUS_LIBRARY file.c

-D defines a macro


Speaking of #embed, honestly, I don’t know what this directive does

Nevertheless, you can write a similar "wrapper" so that this directive is either executed or not:

#ifndef DO_NOT_EMBED_LITERALS
#embed "embedded_literals.txt"
#endif /* DO_NOT_EMBED_LITERALS */

Here we again use #ifndef, i.e. we check that such a macro is NOT defined

If we define DO_NOT_EMBED_LITERALS before this check, then the #embed directive will not be executed

This can be done either by defining it in the code, or by defining it via a command:

$ gcc -DDO_NOT_EMBED_LITERALS file.c
History

0 comment threads

Sign up to answer this question »