0

Classes declarations usually look like that:

#ifndef MY_CLASS_20141116
#define MY_CLASS_20141116

...

class MyClass
{
    ...
}

#endif

My question is, why to not use the class name instead of redefining a new identifier:

#ifndef MyClass

...

class MyClass
{
}

#endif

I guess it has something related with identifier conflicts (a same identifier may appear twice) or the use of namespace (I do not know if a full identifier like std::array may be used in the #ifndef directive).

It would be great a more thorough explanation.

Also, it is possible to use the second test when using namespace?

#ifndef A::MyClass //not compile, any equivalent?

namespace A
{
...

    class MyClass
    {
    }
}
#endif
Adrian Maire
  • 14,354
  • 9
  • 45
  • 85
  • 2
    There are h-files without classes, and h-files with several classes. Regarding your second question, don't expect from preprocessor to be as smart as compiler. – Alex F Nov 16 '14 at 12:57
  • You are right, but in the (very common) case where there is only one class in the header? – Adrian Maire Nov 16 '14 at 12:59
  • There is also `#pragma once` which takes care of this problem for you. While it is non-standard, it is supported by all common compilers. – Baum mit Augen Nov 16 '14 at 13:01
  • `#ifndef` is handled by the preprocessor, not the compiler. The preprocessor does not know anything about namespaces. You can use just simple identifiers. If you define `MyClass`, the preprocessor would also replace `class MyClass`. That is certainly not what you want. – wimh Nov 16 '14 at 13:04
  • As I understand, the preprocessor has access to already defined identifier which include already included class names. So I guess the A::MyClass must have any type of internal identifier/representation for the preprocessor. – Adrian Maire Nov 16 '14 at 13:09
  • @Wimmel: What you mean with "replace"? ifndef/endif should not replace anything, should it? – Adrian Maire Nov 16 '14 at 13:10

1 Answers1

2

First example:

#ifndef MyClass

...

class MyClass
{
}

#endif

This cannot work, because 'MyClass' is never defined for the preprocessor. All directive starting with a # are preprocessor directives and are the only ones the preprocessor understands. class MyClass has no special meaning for the preprocessor, and won't create a preprocessor definition.

For it to work, you have to define MyClass : #define MyClass. However, by doing this, the preprocessor will replace class MyClass by class, which won't compile.

Now, second example:

#ifndef A::MyClass //not compile, any equivalent?

A::MyClass is not a preprocessor token, it is several tokens. #define SOMETHING only work with one token (which is composed of the characters a-zA-Z_0-9).

Synxis
  • 9,236
  • 2
  • 42
  • 64
  • You are right, i though the MyClass was visible for future preprocessor operations, and i missed in my test. Thank you. – Adrian Maire Nov 16 '14 at 13:15