Author Topic: Forward declarations  (Read 6558 times)

sethjackson

  • Guest
Forward declarations
« on: January 22, 2006, 12:54:31 am »
Hi I have a question. What in the world are forward declarations, and why are they needed? Sorry that this is such a dumb question.....

Code: cpp
#ifndef EDITOR_H
#define EDITOR_H

#include <wx/wxscintilla.h>
#include <wx/hashmap.h>
#include <wx/datetime.h>

#include "settings.h"
#include "editorbase.h"
#include "printing_types.h"

extern const wxString EDITOR_MODIFIED;

// forward decls
struct cbEditorInternalData; // this is the private data struct used by the editor.
class cbEditor;
class ProjectFile;
class EditorColorSet;
class wxNotebook;

class cbStyledTextCtrl : public wxScintilla
{
    ...
};

#endif // EDITOR_H


Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Re: Forward declarations
« Reply #1 on: January 22, 2006, 01:23:01 am »
Forward declarations are used to tell the compiler something exists when that's all it needs to know, or that something is somewhere else. In other words, it just gives the compiler enough information to do its job.

Sometimes they're used to don't bother the compiler with all the "internals" of a specific type or function. When it's used to tell the compiler it's somewhere else, it just lets the linker do the dirty job of finding it and putting in the final object/shared/executable file.

In your code snippet there's a forward declaration for wxNotebook. If everything in that header file just needs to know it exists, it's a type, it's just a class, nothing else like it occupies x bytes, it has these methods, inherits from this and that other class, then that fordward declaration reduces parsing times.

There's something important there: "... it occupies x bytes...". If you're going to use that type inside another class/struct, then you need to provide more information, if needed. The exception is when you have references and pointers (doesn't matter the type, the compiler knows their size). Of course you cannot call member functions or use member variables if all you have is the forward declaration (the compiler wouldn't have enough information to know if such a function or variable exists there).

But it'sn't just for fun or reduce parsing times, it's sometimes used because it's needed. Try this:

Code: cpp
// header.h
int x;

Code: cpp
// source1.cpp
#include "header.h"

Code: cpp
// source2.cpp
#include "header.h"

Code: cpp
// main.cpp
#include "header.h"

int main()
{
  // does nothing
}

Compile source1.cpp to an object file. Compile source2.cpp to an object file. Compile main.cpp to an object file. Now, try to link those 3 object files and make an executable.

For every object file x exists (it has external linkage). Now, when the linker tries to link those three object files it'll find x three times. What's it supposed to do? Which x should be put in the final file?

Now, change header.h to this:
Code: cpp
// header.h
extern int x;

And add this file:
Code: cpp
// header.cpp <-- nevermind the name
// include header.h if you want or need to
int x;

Try to create the object files again, plus header.cpp, and link them.

Now, header.h says: there's a variable named x, type int, but isn't here. header.cpp says: I have it.

For more information search about linkage.