Should I use forward ads and not include them where possible?
No, explicit forward declarations should not be construed as general guidance. Forward declarations are essentially a copy and paste or an error code, which, if an error is detected, should be recorded everywhere where forward declarations are used. This may be error prone.
To avoid inconsistencies between forward declarations and its definitions, place the declarations in the header file and include this header file in both the source definition files and the declaration.
However, in this special case, when only an opaque class is declared forward, this forward declaration may be in order, but in general “use declarations ahead, and not include when possible,” for example, the header of this thread says it can be quite risky.
Here are some examples of “invisible risks” in relation to forward declarations (invisible risks = declaration inconsistencies that are not detected by the compiler or linker):
Explicit forward declarations of symbols representing data may be unsafe, because such forward declarations may require the correct knowledge of the size (s) of the data type.
Explicit forward declarations of characters representing functions may also be unsafe, for example, parameter types and number of parameters.
The following example illustrates this, for example, two dangerous forward data declarations, as well as functions:
Ac file:
#include <iostream> char data[128][1024]; extern "C" void function(short truncated, const char* forgotten) { std::cout << "truncated=" << std::hex << truncated << ", forgotten=\"" << forgotten << "\"\n"; }
Bc file:
#include <iostream> extern char data[1280][1024]; // 1st dimension one decade too large extern "C" void function(int tooLarge); // Wrong 1st type, omitted 2nd param int main() { function(0x1234abcd); // In worst case: - No crash! std::cout << "accessing data[1270][1023]\n"; return (int) data[1270][1023]; // In best case: - Boom !!!! }
Compiling a program using g ++ 4.7.1:
> g++ -Wall -pedantic -ansi ac bc
Note. Invisible danger, since g ++ does not give errors / warnings to the compiler or linker
Note. Omitting extern "C" results in a binding error for function() due to a C ++ name change.
Launching the program:
> ./a.out truncated=abcd, forgotten="♀♥♂☺☻" accessing data[1270][1023] Segmentation fault