c++macros

C++ macro preprocessor string concatenation


I've read the various other questions on this but they either don't work or I'm otherwise stuck.

I'm trying to dynamically #import a file based on build flags where my imported file name is of the form:

hardware_<hardware>_<version>.h

I can make it work, but only without the .h file extension, which isn't ideal.

How do I modify this to have .h on the end?

./hardware_XXX_YYY:

#define FOO "bar"

./main.cpp:

#include <iostream>   

#define HARDWARE XXX
#define HARDWARE_VERSION YYY

#define CCC(x) #x

// This fails:
//#define BBB(ha, ver) CCC(hardware_##ha##_##ver##.h)

// This works:
#define BBB(ha, ver) CCC(hardware_##ha##_##ver)

#define AAA(ha, ver) BBB(ha, ver)

#include AAA(HARDWARE, HARDWARE_VERSION)

int main() {
    
    std::cout << FOO  << '\n';
}

Solution

  • You don't need the extra ## before the .h part, as the .h is not part of the token parsing (the ha and ver is, and you need an extra ## because of the underscore).

    Here is a tiny example that includes "string.h" built up by macros. Again, st and .h is not part of the concatenating, therefore no need for extra ##s.

    #include <iostream>   
    
    #define CCC(x) #x
    #define BBB(ha, ver) CCC(st##ha##ver.h)
    
    #include BBB(ri,ng)
    
    int main() {
        
        std::cout << BBB(ri,ng)"\n";
    }
    

    Output:
    string.h