Multi-pass C preprocessor [closed] - c-preprocessor

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Is it remotely sane to apply the C preprocessor to the same codebase multiple times (specifically, twice in sequence?)
For instance, having declarations such as the following:
##define DECLARE(FILE) # define DECLARATIONS \
# include FILE \
# undef DECLARATIONS
Have you ever seen such an idiom before? If so, what codebase? Can you link it? What sort of patterns would be followed to compile a project doing something like this? Can the CPP as it stands be made to do this, or do I need to write a meta-preprocessor to “hide” the single-hash declarations while processing the double-hash declarations, and so on?

I think when you need multiple CPP passes, you might want to consider m4 or some other sophisticated macro system/code generator. I think it will be hard to do what you want, and since you are going to be changing your build process for this anyway, look at other templating or macro systems.

Oh wow, why would you want to do this? I am sure GCC could be coerced into doing something like this with some clever make tricks (use the -E flag for GCC) but I can't imagine anyone being able to maintain it later.

Google threw this up, so here's a four-years-late use case for multiple (pre)compilation passes.
The largest benefit to multiple-pass compilation that I can see comes from optionally preprocessing the file. Specifically, when one would like to see the preprocessed source without including the very large standard headers at the top. E.g.,
#ifdef PRECOMPILATION
#ifdef TMPINCLUDE
#error "This stunt assumes TMPINCLUDE isn't already defined"
#endif
#define TMPINCLUDE #include <stdlib.h>
TMPINCLUDE
#undef TMPINCLUDE
#else
#include <stdlib.h>
#endif
This will compile as normal in the absence of PRECOMPILATION, but if compiled as gcc -E -P -DPRECOMPILATION or similar, will translate into a source file containing all your code, post expansion, and the #include statement at the top. So it's still valid code and can also be compiled from the already-preprocessed file.
Macros are unpopular in the C and C++ world. I would like to release a plausibly useful library to the wider world, but it's very heavily based on macros to reduce code duplication. Using an either-one-or-two pass compilation model means I can use the library directly, macros and all, in my own work, but can also release a sanitised version which only uses the preprocessor to include standard libraries.
Whether that is remotely sane or not is rather subjective.

Related

Why does the standard C library feature multiple header files instead of consolidating the contents into a single header? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 months ago.
Improve this question
Why does the standard C library need to feature multiple header files? Would it not be more user friendly to consolidate it into one header file?
I understand that it is unnecessary to include function prototypes / global variables that go unused, however, won't the compiler eventually remove all of these references if they're unused?
Maybe I'm underestimating the size of contents spanning all of the header files. But it seems like I'm always googling to figure out what header I need to #include.
Edit: The top comment references a size of 50MB which appears to be untrue. The C library is relatively concise compared to other language's standard libraries hence the question.
// sarcasm ON
Build your own #include "monster.h" that includes all you want from the collection.
People write obfuscated code all the time. But, you won't be popular with your cohort.
// sarcasm OFF
The real reason? C was developed when storage was barely beyond punch card technology. A multi-user system might have 1/2Mb of (magnetic) core memory and a cycle time that is now laughable.
Yet, reams of C code was developed (and the story of the popularity of UNIX well known.)
Although new standards could change the details (and C++ has), there is an ocean of code that might/would no longer be able to be compiled.
Look up "Legacy".
There are (too many) examples of code in the world where the usual collection of, say, stdio.h, stdlib.h, etc. have been "hidden" inside #include "myApp.h". Doing so forces the reader to hunt-down a second file to verify what the &^%&%& is going on.
Get used to it. If it was a bad practice, it would not have survived for ~50 years.
EDIT: It is for a similar reason that "functions" have been "grouped together" into different libraries. By extension, pooling those libraries might make things a tiny bit "less cluttered", but the process of linking may require a supercomputer to finish the job before knock-off time.
EDIT2: Brace yourself. Cleanly written C++ code often has a .h and a .cpp for every class used in the app. Sometimes "families" (hierarchies) might live together in a single pair of files, although that can lead to boo-boo's when the coder is having a bad day...

How many headers for a c-module? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I have a module in my project mymodule.c that provides a lot of functions for the rest of my project.
These function are defined in a mymodule.h header file.
But in mymodule.c there are a lot of other defines or define masks.
For example:
#define STACKSIZE 1024
#define TIMER1 100
#define TCR_MASK 16U
#define TCR 16U
#define TCR_IR (0ULL << 8)
...
100 other defines or typedefs
I could split it up like this:
mymodule.h --->all external functions and declarations used from other places.
Rename this to mymodule_public.h ?
mymodule_config.h ---> configuration like timers, controlparameters or constants.
mymodule_masks.h ---> decsriptors.
There could be more headers.
Another way is to keep all except the external functions in the mymodule.c.
What is best practice for splitting up into headers and giving header names?
Generally, a header file which is the public interface of a library should contain all the things that the caller needs to use the functions.
If you have a bunch of #define that are necessary to use the functions, they need to be in the h file. If they aren't needed but just used internally, you should keep them in the c file.
It is ok to make a 2nd header file which isn't the public API but just contains internal constants used by your c file(s).
As for where to place the #includes, that's a bit subjective. Generally I like to show the user of the library which dependencies the library comes with, so that they can ensure that they have all the necessary files and so that they can trouble-shoot strange linker errors easier. On the other hand, one might feel uneasy about "exposing" includes that are just used privately by the library in the public header (like the 2nd private header mentioned above). There's no obvious right or wrong here, though try to be consistent with where you place the #includes.
Your idea with multiple headers all named with a certain library-specific prefix "mymodule" is pretty sound overall.

Optimizing includes in C [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
My project has several header files. Most of C source files include all of those, so nearly every source file contains the following lines:
#include "add.h"
#include "sub.h"
#include "mul.h"
#include "div.h"
#include "conv.h"
#include "comp.h"
// etc.
Should this be moved to some all.h or similar? Is there a better way to do this?
In each .c file it should be easy to know what includes it needs. By doing your way, you could lose track of what includes it needs, and another colleague will need to look for this file.
In another words, you shouldn't do that because you lose clarity in your code.
There is also the third, somewhere-in-the-middle option, to have a minimum common.h for stuff which is shared by pretty much all your translation units (e.g. headers like stdint.h). Or perhaps you might decide to group add.h, sub.h and similar headers into a single ops.h header.
But having literally a single all.h header would make encapsulation/information hiding in C even harder than it is already. Does a math library in a spaceship microcontroller really need to know everything about life support systems?
Of course, C doesn't really have "first class encapsulation mechanisms", you can throw an extern function declaration pretty much everywhere, that's why it's rather important to stick to reasonable conventions and best practices.
There are pro and conses in both approaches (having one single all.h including all your headers, or not), so it is also a matter of opinion. And on a reasonably small project, having a single header file containing all your common declarations (and also definitions of static inline functions) is also possible.
See also this answer (which gives examples of both approaches).
A possible reason to have one single header (which includes other headers, even the system ones) is to enable pre-compilation of that header file. See this answer (and the links there).
A possible reason to favor several header files is readability and modularity. You might want to have one (rather small) header file per module and in every translation unit (practically every .c file) you would include only the minimal set of header files (in the good order).
Remember that C99 & C11 (and even C++14) do not have any notion of modules; in other words, modules in C are only a matter of conventions & habits. And conventions and habits are really important in C programs, so look at what other people are doing in existing free software projects (e.g. on github or sourceforge).
Notice that preprocessing is the first phase of most C compilers. Read documentation about your C preprocessor.
You practically would use a build automation system like GNU make. You may want to automatically generate dependencies (e.g. like here).
For a single-person project (of a few dozens of thousand source lines at most), I personally prefer to have a single header file, but that is a matter of opinion and taste (so a lot of people disagree). BTW, refactoring your project (to several header files) when it becomes large enough is quite easy to do (but harder to design); you'll just copy&paste some chunks of code in several new header files.
For a project involving several developers, you may want to favor the idea that most files (header or code) have one single developer responsible for them (with other developers making occasional changes to it).
Notice that header inclusion and preprocessing is a textual operation. You might in theory even avoid having header files and copy and paste the same declarations in your .c files but that is very bad practice so you should not do that (in hand-written code). However, some projects are generating C code (some sort of metaprogramming), and their C code generator (some script, or some tool like bison) could emit the same declarations in several files.

What does #pragma once mean in C? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
#pragma - help understanding
I saw the pragma many times,but always confused, anyone knows what it does?Is it windows only?
It's used to replace the following preprocessor code:
#ifndef _MYHEADER_H_
#define _MYHEADER_H_
...
#endif
A good convention is adding both to support legacy compilers (which is rare though):
#pragma once
#ifndef _MYHEADER_H_
#define _MYHEADER_H_
...
#endif
So if #pragma once fails the old method will still work.
2023 update
I see some people in the comment section advocate for using guards instead of #pragma once.
This makes little to no sense in 2023 and beyond unless you are targeting some special compiler that you know does not support #pragma once.
Today's best practice is to use only #pragma once and don't bother with guards at all. Reasons being
All major compilers been supporting this forever and that is not
going to change.
Using #pragma allows the compiler to use its internal caches which is of course faster than using the pre-processor which will always include the contents of your file just to later stumble on your guards and dismiss the whole thing.
It's a lot shorter and easier to add/maintain
In the C and C++ programming
languages, #pragma once is a
non-standard but widely supported
preprocessor directive designed to
cause the current source file to be
included only once in a single
compilation. Thus, #pragma once serves
the same purpose as #include guards,
but with several advantages,
including: less code, avoiding name
clashes, and improved compile speed.
See the Wikipedia article for further details.
Generally, the #pragma directives are intended for implementing compiler-specific preprocessor instructions. They are not standardized, so you shouldn't rely on them too heavily.
In this case, #pragma once's purpose is to replace the include guards that you use in header files to avoid multiple inclusion. It works a little faster on the compilers that support it, so it may reduce the compilation time on large projects with a lot of header files that are #include'ed frequently.
pragma is a directive to the preprocessor. It is usually used to provide some additional control during the compilation. For example do not include the same header file code. There is a lot of different directives. The answer depends on what follows the pragma word.

What is a good reference documenting patterns of use of ".h" files in C? [duplicate]

This question already has answers here:
Should I use #include in headers?
(9 answers)
Closed 7 years ago.
"C Interfaces and Implementations" shows some interesting usage patterns for data structures, but I am sure there are others out there.
http://www.amazon.com/Interfaces-Implementations-Techniques-Addison-Wesley-Professional/dp/0201498413
Look at the Goddard Space Flight Center (NASA) C coding standard (at this URL). It has some good and interesting guidelines.
One specific guideline, which I've adopted for my own code, is that headers should be self-contained. That is, you should be able to write:
#include "header.h"
and the code should compile correctly, with any other necessary headers included, regardless of what has gone before. The simple way to ensure this is to include the header in the implementation source -- as the first header. If that compiles, the header is self-contained. If it doesn't compile, fix things so that it does. Of course, this also requires you to ensure that headers are idempotent - work the same regardless of how often they are included. There's a standard idiom for that, too:
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
...operational body of header.h...
#endif /* HEADER_H_INCLUDED */
It is imperative, of course, to have the #define at the top of the file, not at the bottom. Otherwise, if a header included by this also includes header.h, then you end up with an infinite loop - not healthy. Even if you decide to go with a strategy of:
#ifndef HEADER_H_INCLUDED
#include "header.h"
#endif /* HEADER_H_INCLUDED */
in the code that include the header - a practice which is not recommended - it is important to include the guards in the header itself too.
Update 2011-05-01
The GSFC URL above no longer works. You can find more information in the answers for the question Should I use #include in headers, which also contains a cross-reference to this question.
Update 2012-03-24
The referenced NASA C coding standard can be accessed and downloaded via the Internet archive:
http://web.archive.org/web/20090412090730/http://software.gsfc.nasa.gov/assetsbytype.cfm?TypeAsset=Standard
Makeheaders is an interesting approach: use a tool to generate the headers. Makeheaders is used in D. R. Hipp's cvstrac and fossil.
You might want to take a look at Large-Scale C++ Software Design by John Lakos.

Resources