How do I use a preprocessor macro inside an include?

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-04 12:22:06

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/42858048/how-do-i-use-a-preprocessor-macro-inside-an-include

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!