Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a preprocessor macro inside an include?

I am trying to build freetype2 using my own build system (I do not want to use Jam, and I am prepared to put the time into figuring it out). I found something odd in the headers. Freetype defines macros like this:

#define FT_CID_H  <freetype/ftcid.h>

and then uses them later like this:

#include FT_CID_H 

I didn't think that this was possible, and indeed Clang 3.9.1 complains:

error: expected "FILENAME" or <FILENAME>
#include FT_CID_H
  • What is the rationale behind these macros?
  • Is this valid C/C++?
  • How can I convince Clang to parse these headers?

This is related to How to use a macro in an #include directive? but different because the question here is about compiling freetype, not writing new code.

like image 217
sdgfsdh Avatar asked Mar 17 '17 12:03

sdgfsdh


People also ask

Can we use macro inside macro?

Here is an example of how to run another macro from a macro using the Call Statement. Just type the word Call then space, then type the name of the macro to be called (run). The example below shows how to call Macro2 from Macro1. It's important to note that the two macros DO NOT run at the same time.

What is a #include preprocessor?

The #include directive tells the C preprocessor to include the contents of the file specified in the input stream to the compiler and then continue with the rest of the original file. For example, the header file, file.h contains the following: char *func (void);

Can we use #define inside main?

You can use #define anywhere you want. It has no knowledge of functions and is not bound by their scope.

Can I #define in a macro?

Macros using #define A macro is a fragment of code that is given a name. You can define a macro in C using the #define preprocessor directive. Here's an example.


2 Answers

I will address your three questions out of order.

Question 2

Is this valid C/C++?

Yes, this is indeed valid. Macro expansion can be used to produce the final version of a #include directive. Quoting C++14 (N4140) [cpp.include] 16.2/4:

A preprocessing directive of the form

# include pp-tokens new-line

(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined.

The "previous forms" mentioned are #include "..." and #include <...>. So yes, it is legal to use a macro which expands to the header/file to include.

Question 1

What is the rationale behind these macros?

I have no idea, as I've never used the freetype2 library. That would be a question best answered by its support channels or community.

Question 3

How can I convince Clang to parse these headers?

Since this is legal C++, you shouldn't have to do anything. Indeed, user @Fanael has demonstrated that Clang is capable of parsing such code. There must be some problem other problem in your setup or something else you haven't shown.

like image 96
Angew is no longer proud of SO Avatar answered Sep 25 '22 00:09

Angew is no longer proud of SO


Is this valid C/C++?

The usage is valid C, provided that the macro definition is in scope at the point where the #include directive appears. Specifically, paragraph 6.10.2/4 of C11 says

A preprocessing directive of the form

# include pp-tokens new-line

(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) The directive resulting after all replacements shall match one of the two previous forms.

(Emphasis added.) Inasmuch as the preprocessor has the same semantics in C++ as in C, to the best of my knowledge, the usage is also valid in C++.

What is the rationale behind these macros?

I presume it is intended to provide for indirection of the header name or location (by providing alternative definitions of the macro).

How can I convince Clang to parse these headers?

Provided, again, that the macro definition is in scope at the point where the #include directive appears, you shouldn't have to do anything. If indeed it is, then Clang is buggy in this regard. In that case, after filing a bug report (if this issue is not already known), you probably need to expand the troublesome macro references manually.

But before you do that, be sure that the macro definitions really are in scope. In particular, they may be guarded by conditional compilation directives -- in that case, the best course of action would probably be to provide whatever macro definition is needed (via the compiler command line) to satisfy the condition. If you are expected to do this manually, then surely the build documentation discusses it. Read the build instructions.

like image 25
John Bollinger Avatar answered Sep 25 '22 00:09

John Bollinger