3

This is a weird problem that I was wondering if anyone else had seen. We're writing cross-platform C++ code for Mac and PC, and this only occurs on Mac.

Say I have a class, whose .h file looks like this.

class X {
public:
    int _myValue;
    void myFunction();
}

And I have another class, whose .h file looks like this:

#include "X.h"
class Y {
private:
     X _myObj;
}

This won't compile. We get an error indicating X is undefined. The solution is to add a forward declaration for X in the Y.h file, such as: class X;

We've been doing this for a while, but now we're getting into situations where it's not working so well. For example, if we have a .h file that has a templates method defined in the .h file, and that method references a method in another class, the compiler doesn't know anything about it. Likewise, if we reference an enum that's defined in a class that was included, the compiler doesn't recognize it (the workaround for this problem was to put the enum in a separate .h file, and it picked it up just fine).

It's almost as if while compiling the .cpp file the compiler isn't pulling in the data from the included .h file.

I was just wondering if anyone had seen anything like this, or had possible avenues of investigation.

Much thanks...

6
  • #include "X.h" or 'include "x.h"? Are you getting any warnings such as "failed to find 'X.h'"? Commented Mar 14, 2012 at 17:07
  • 1
    Can you post an actual minimal example that exhibits the problem you're having (including the cpp file)? When I try to compile your header files, the compiler rightly complains that your class declarations are missing semicolons at the end. When I fix this, the code compiles fine with gcc 4.2 under Mac OS. (My suspicion is that your actual header files contain include guards or #pragma once and that your problem is related to this.) Commented Mar 14, 2012 at 17:10
  • You might want to look to see if you have an old copy of the X.h header sitting around which is being picked up by the compiler instead of the latest header. Commented Mar 14, 2012 at 18:32
  • Where are the headers stored? Check you Project Settings Build Tab. Scroll down to the Search Paths section and make sure your headers can be found. Also read the help for Always Search User Paths, although that's probably off topic. Commented Mar 14, 2012 at 19:09
  • It's important to remember that the Apple default file system doesn't distinguish case. So "X.h" and "x.h" are the same file name. Commented Mar 14, 2012 at 19:17

3 Answers 3

1

There is a common system header file X.h which is part of the X11 windowing toolkit. I recommend changing the name of your header file so that it doesn't clash with any system headers.

You could try to alter your compiler switches to force it to consider the directory containing your header file before your system include directories but this is probably more effort and more fragile.

Sign up to request clarification or add additional context in comments.

Comments

0

For your first issue (classes), the correct answer is to use a forward declaration. You should avoid including project include files in other project include files. This can create include loops (which is most likely your issue if I had to guess). It also creates excessive build churn when you modify a header.

For your other issues (enums, templates), this is usually due to include cycles. Breaking those cycles by avoiding includes whenever possible is your best bet.

For more discussion on this issue and best practices, see Header file best practices for typedefs.

2 Comments

A forward declaration (only) in Y.h is not appropriate as X appears as a value member of Y. A full definition of X is required.
You're absolutely correct in this case. You should avoid the include when possible, but as you note, it's not possible in this case.
0

I'm just a touch surprised that no one else has mentioned the canonical scheme for include files, eg,

foo.h:

#ifndef FOO_H
#define FOO_H
// body of the include file
#endif

I suspect that in this specific case, the clash of "x.h" and "X.h" may be the issue you're seeing, but if you don't guard the include files like this it will bite you eventually.

With that guard, you can include "x.h" anywhere you need it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.