9

Let's assume I define BAR in foo.h. But foo.h might not exist. How do I include it, without the compiler complaining at me?

#include "foo.h"

#ifndef BAR
#define BAR 1
#endif

int main()
{
    return BAR;
}

Therefore, if BAR was defined as 2 in foo.h, then the program would return 2 if foo.h exists and 1 if foo.h does not exist.

theanine
  • 986
  • 3
  • 10
  • 21

2 Answers2

9

In general, you'll need to do something external to do this - e.g. by doing something like playing around with the search path (as suggested in the comments) and providing an empty foo.h as a fallback, or wrapping the #include inside a #ifdef HAS_FOO_H...#endif and setting HAS_FOO_H by a compiler switch (-DHAS_FOO_H for gcc/clang etc.).

If you know that you are using a particular compiler, and portability is not an issue, note that some compilers do support including a file which may or may not exist, as an extension. For example, see clang's __has_include feature.

Matthew Slattery
  • 45,290
  • 8
  • 103
  • 119
  • The 2nd foo.h fallback file is the simplest solution. – theanine Jul 20 '12 at 16:51
  • 1
    It's also a bad solution because if the real `foo.h` changes its internal header-guard `#define`, you get subtle breakage. – Jack Kelly Jul 22 '12 at 07:07
  • 1
    Why? The fallback foo.h is empty. – theanine Jul 24 '12 at 17:32
  • I guess Jack misread HAS_FOO_H as something that is defined inside the real foo.h. But Jack has a point. The fallback foo.h should not be empty. It should define a symbol indicating that the fallback was used. It's better than relying on any symbol from the real foo.h. API can change, macros can change to C constants. – proski Feb 23 '15 at 22:01
8

Use a tool like GNU Autoconf, that's what it's designed for. (On windows, you may prefer to use CMake).

So in your configure.ac, you'd have a line like:

AC_CHECK_HEADERS([foo.h])

Which, after running configure, would define HAVE_FOO_H, which you can test like this:

#ifdef HAVE_FOO_H
#include "foo.h"
#else
#define BAR 1
#endif

If you intend to go down the autotools route (that is autoconf and automake, because they work well together), I suggest you start with this excellent tutorial.

Jack Kelly
  • 18,264
  • 2
  • 56
  • 81
  • Autotools can be ... well, painful, and it's completely unnecessary these days. Mac and Linux have excellent CMake support, and there are other nice build systems (like [SCons](http://www.scons.org/)). ESR has a particularly poignant post that's worth considering: [Autotools must die](http://esr.ibiblio.org/?p=1877). – sfstewman Jul 25 '12 at 01:14
  • 5
    The pain that CMake inflicts far exceeds autotools'. http://news.ycombinator.com/item?id=2357014 . It forces a MSVC-inspired model of build types onto unix land, comes with a new clumsy programming language that is missing proper data structures, extended in an ad-hoc fashion with random things built-in (qt4!? fltk!?). ESR's rant is all vitriol and no substance. I've used CMake, SCons and autotools across several projects and I'll go autotools almost every time. To replace autotools, you need to not compile to makefiles. `make`'s model is subtly broken and a replacement must understand that. – Jack Kelly Jul 25 '12 at 05:32