简体   繁体   中英

String concatenation for include path

Is there a way to concatenate 2 strings literals to form an include path?

Code stub:

#define INCLUDE_DIR "/include"
#include INCLUDE_DIR "/dummy.h"

Looking at this question , the answers point in a different direction (compiler command line). It is mentioned here that it is seemingly not possible, but I wonder if the topic has been dug enough.

(I do have an use case in which this is relevant, please focus your answers/comments on this question only.)

I'm not sure that this is exactly what you want but anyway.

#define DECORATE(x)             <x>
#define MAKE_PATH(root, file)   DECORATE(root file)

#define SYS_DIR(file)           MAKE_PATH(sys/, file)
#define ARPA_DIR(file)          MAKE_PATH(arpa/, file)


#include SYS_DIR(types.h)
#include SYS_DIR(socket.h)
#include ARPA_DIR(inet.h)

Note, that generated filenames contain extra space - <sys/ types.h> , so it may not be a cross-compiler solution. But at least for me it works on Linux host on GCC 4.8 / 4.9.

PS It would be nice if someone could check this snippet with another compilers, eg MSVC.

It really seems this is not possible. I will report here the relevant section from Eric Postpischil's answer (he doesn't seem to be active anymore).

The compiler will do macro replacement on an #include line (per C 2011 [N1570] 6.10.2 4), but the semantics are not fully defined and cannot be used to concatenate file path components without additional assistance from the C implementation. So about all this allows you to do is some simple substitution that provides a complete path, such as:

 #define MyPath "../../path/to/my/file.h" #include MyPath 

Link to documentation . In particular this section doesn't leave much hope for portable solutions:

The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.


For completeness, maybe something can be tried using https://stackoverflow.com/a/27830271/2436175 . I'll investigate that when I have a moment...

Simply avoid the space and the concatenation (##) and use the < > it makes all simplier:

#include <QtCore/QtGlobal>

#define QT_VERSION_PREFIX QT_VERSION_MAJOR.QT_VERSION_MINOR.QT_VERSION_PATCH

#define _CONCATE(a, c) <a/QT_VERSION_PREFIX/a/private/c>
#include _CONCATE(QtWidgets, qwidgettextcontrol_p.h)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM