6

First of all, I've read this question: Is there a way to detect portably that a standard header is included using macros?

And what I want to know is: How safe is it to use #ifdef for the task of detecting if a c++ std header is included, like in the code below:

namespace overwrite
{
    using byte = unsigned char;

    template <bool safeMode = true, typename generic>
    void withZeros( generic *toBeOverwriten, size_t length = 1 )
    {
         // do stuff
    }

    #ifdef _GLIBCXX_RANDOM // found this macro inside <random>
    template <bool safeMode = true, typename generic>
    void withRandomData( generic *toBeOverwriten, byte min = 0, byte max = 255 )
    {
        // do stuff expecting <random> to be included
    }
    #endif
}

...so that I could not just overload some std function as "worse match" as proposed in the answer to the mentioned question, but also compile or not a whole function/section of My header file, depending on the inclusion of some std header.

Is this way not safe at all, as I suspect? If so, are there any other ways to detect this in order to do what I want to?

Regarding to "Why the heck don't I just include the header"...

The code I give as an example of what I'm trying to do is Just An Example. I had other things in my mind too and just wanted to know if there was another way to check for the inclusion of headers without checking macros you expect to be defined inside those. Then I remembered of this real situation where I asked myself about this and I started by asking what I'm asking... since, in this given case, I don't want to include a lot of code (<random> is longer than 20 or 30 LOC) just to "sustain" a single function of my header.

Community
  • 1
  • 1
Pedro V. G.
  • 353
  • 1
  • 4
  • 13
  • 1
    Just include the header? – Daniel Oct 31 '15 at 18:38
  • BTW, why don't you simply #include random? – Karoly Horvath Oct 31 '15 at 18:40
  • I could just include the header, of course, but I want to know if it's possible to do what I've proposed... – Pedro V. G. Oct 31 '15 at 18:41
  • Can you clarify what problem it would solve? Unless that's what you want to truly know. – edmz Oct 31 '15 at 18:47
  • 1
    The case of std headers was one of some I thought about. But the only real problems I see related to this is **1)** that I have a header defining a red-black tree and another defining a shuffle function and I wanted to include a member function to my red black tree, which returns a shuffled list of its elements, IF shuffle function is there too (in other worlds: if `shuffle.hpp` is included...) and **2)** also, I just wanted to have the `overwrite::withRandomData` if `` is already included because I do not want to include a lot of code just to "sustain" this single function. – Pedro V. G. Oct 31 '15 at 18:59
  • The answer is modules: "Modules will fix everything". – edmz Oct 31 '15 at 20:18
  • I took a read about modules... it looks very interesting and kinda ~revolutionary~ indeed – Pedro V. G. Nov 03 '15 at 01:49

1 Answers1

3

There is a proposal for c++17 to add the __has_include macro.

The latest version isn't public yet, but was discussed (approved?) at the last standard meeting: https://www.reddit.com/r/cpp/comments/3q4agc/c17_progress_update_oct_2015/

The previous version: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0061r0.html


Until then I don't think there is a portable way of detecting if a header is available. The best you can do is to check what macro a header defines, bearing in mind that different libraries have different macros and that even in the same libraries the name can change from revision to revision, as it is an internal macro. It's not that bad if you only want to support the major compilers (there are 3) and don't expect your code to be supported 3-5 years from now.

Instead of checking for a header, if it's possible you should check for features. C++11 onward defines a set of feature testing macros:

http://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros

bolov
  • 72,283
  • 15
  • 145
  • 224
  • Very interesting links, specially this one about feature testing... But `__has_include` looks kinda far away from now :( – Pedro V. G. Oct 31 '15 at 19:11
  • `__has_include` is in C++17, but note that it doesn't exactly solve the OP's problem: there's a difference between checking whether a header _can be_ included and checking whether it _has been_ included. `__has_include` does the former, whereas the OP seems to be asking about the latter. – deltacrux Oct 05 '21 at 06:27