Why is this a forward declaration in C++?

c++, forward-declaration, language-lawyer, standards

Solution

In line 0, you declared a class named `tm` inside the `xm` namespace. Yes, C++ allows declaring types in function/template parameters.

N4140 § 3.4.4 [basic.lookup.elab]/2

If the elaborated-type-specifier is introduced by the class-key and this lookup does not find a previously declared type-name, or if the elaborated-type-specifier appears in a declaration with the form:

class-key attribute-specifier-seqopt identifier;

the elaborated-type-specifier is a declaration that introduces the class-name as described in 3.3.2.

Because you declared a class named `tm` inside the `xm` namespace, it's the first name that name lookup finds for `tm` in line 3. `::tm` (and `::std::tm`) are not considered. And since there's no definition of class `::xm::tm`, the compiler complains about it being an incomplete type.

If you weren't writing C code in C++, you'd write something like1

struct tm;

namespace xz{
    void zoo(tm timeval);
}

or

#include <ctime>

namespace xz{
    void zoo(tm timeval);
}

and you wouldn't have that problem.

1 remember that you cannot forward-declare names in namespace std

Problem

I will have the following code snippet in utilA.cpp: ``` // utilB.h namespace xm { void zoo(struct tm timeval); //<-----line 0 } // utilA.cpp #include <utilB.h> //<----line 1 #include <time.h> //<----line 2 namespace xm { void foo() { struct tm time1 = {0}; //<----line 3 } } ``` GCC complains when compiling utilA.cpp, ``` error: variable 'xm::tm time1' has initializer but incomplete type ``` It seems this is because the `utilA.h` is using `struct tm` in line 0, but without include the `time.h`, and the compiler treat the `struct tm` in line 0 as a forward declare, so the `struct tm` at line 2 is resolved as `xm::tm` inside the header at line 0. So does the C++ standard define this `struct tm` as an type of function parameter as forward declaration? Please help to explain this and quotes from the standard will helpful.

Original source