Go to main content
Oracle® Developer Studio 12.6: C++ User's Guide

Exit Print View

Updated: July 2017
 
 

5.1 Header Files

Creating an effective header file can be difficult. Often your header file must adapt to different versions of both C and C++. To accommodate templates, make sure your header file is tolerant of multiple inclusions (idempotent).

5.1.1 Language-Adaptable Header Files

You might need to develop header files for inclusion in both C and C++ programs. However, Kernighan and Ritchie C (K&R C), also known as “classic C,” ANSI C, Annotated Reference Manual C++ (ARM C++), and ISO C++ sometimes require different declarations or definitions for the same program element within a single header file. (See the C++ Migration Guide for additional information on the variations between languages and versions.) To make header files acceptable to all these standards, you might need to use conditional compilation based on the existence or value of the preprocessor macros __STDC__ and __cplusplus.

The macro __STDC__ is not defined in K&R C, but is defined in both ANSI C and C++. Use this macro to separate K&R C code from ANSI C or C++ code. This macro is most useful for separating prototyped from non-prototyped function definitions.

#ifdef __STDC__
int function(char*,...);      // C++ & ANSI C declaration
#else
int function();               // K&R C
#endif

The macro __cplusplus is not defined in C, but is defined in C++.


Note -  Early versions of C++ defined the macro c_plusplus instead of __ cplusplus. The macro c_plusplus is no longer defined.

Use the definition of the __cplusplus macro to separate C and C++. This macro is most useful in guarding the specification of an extern “C” interface for function declarations, as shown in the following example. To prevent inconsistent specification of extern “C”, never place an #include directive within the scope of an extern “C” linkage specification.

#include “header.h”
...                     // ... other include files...
#if defined(__cplusplus)
extern “C” {
#endif
  int g1();
  int g2();
  int g3()
#if defined(__cplusplus)
}
#endif

In pre-standard (ARM) C++, the __cplusplus macro had a value of 1. In ISO C++, the macro has a value reflecting the version of the C++ standard the compiler is following. The value is the date of adoption of the standard, as follows:

C++ 1998/2003: 199711L
C++ 2011: 201103L
C++ 2014: 201402L 

Notes for Oracle Developer Studio 12.6:

  1. Pre-standard C++ is not supported, so the macro never has the value 1.

You can use the value of this macro to determine whether constructs introduced in a newer version of the standard are available in the current compilation mode.

For example, suppose you want to use the “final” qualifier on a class or virtual function, but the code might be compiled in C++03 mode where the feature is not available. You can write this:

#if __cplusplus >= 201103L
#define FINAL final
#else
#define FINAL
#endif
class A FINAL
{
    // ...
};

5.1.2 Idempotent Header Files

Your header files should be idempotent, that is, the effect of including a header file many times should be exactly the same as including the header file only once. This property is especially important for templates. You can best accomplish idempotency by setting preprocessor conditions that prevent the body of your header file from appearing more than once.

#ifndef HEADER_H
#define HEADER_H
/* contents of header file */
#endif