Reputation: 24750
This one is making me scratch my head too long.
I have the following in a header test.h:
inline void anything(){
std::cout<<" anything "<<ii;
}
Then I have a.h, which includes test.h:
class Fooness{
public:
Fooness(){
anything(); //compiler reports "use of undeclared identifier"
};
};
HOWEVER, if I simply move the function definition to a.cpp:
Fooness::Fooness(){
anything();
}
It works. a.cpp includes test.h which includes a.h. Why is anything()
only visible in a.cpp not a.h?
Upvotes: 2
Views: 93
Reputation: 45665
As you pointed out in the comments, you included a.h
in test.h
and vice versa. This introduces errors as functions and classes being "undefined" because of a cyclic dependency, also known as cross-include.
In your case, when a .cpp
file includes test.h
, it first includes a.h
and then defines the function anything();
, which is obviously not what you want, since when processing a.h
, anything()
is undefined.
Your code expands to something similar to this, when compiling a unit which includes test.h
(before a.h
), which by itself includes a.h
before anything else:
/* INCLUDED FROM a.h */
class Fooness{
public:
Fooness(){
anything();
};
};
inline void anything() {
....
}
As you see, there is no anything()
defined when you use it. However, if a compilation unit includes a.h
(before test.h
), which itself includes test.h
, it expands to something like this:
/* INCLUDED FROM test.h */
inline void anything() {
....
}
class Fooness{
public:
Fooness(){
anything();
};
};
So the order is correct.
To make it work in both situations, you can forward-declare anything()
in test.h
before you include a.h
:
Corrected version of test.h:
#ifndef TEST_H
#define TEST_H
void anything(); // forward-declaration
#include "a.h" // <-- this is important to be *below* the forward-declaration
inline void anything() {
....
}
// more stuff
#endif
Then, when including test.h
(before a.h
), it expands to the following:
void anything();
/* INCLUDED FROM a.h */
class Fooness{
public:
Fooness(){
anything();
};
};
inline void anything() {
....
}
Upvotes: 2
Reputation: 7119
make sure that "undeclared identifier" is about anything()
and not about ii
which I see in operator<<
...
Upvotes: 1