#include<iostream>
using namespace std;
struct a{
int e;
struct abc *d;
};
struct abc{
int c;
};
int main()
{
return 0;
}
I have defined the struct abc
after definition of struct a
in which i have declared a structure pointer for abc
. This is supposed to throw compilation error because abc
is used before its declaration. But, it doesn't, why?
Whereas when i replace it with just struct abc d
instead of struct abc *d
, it is giving compilation error as expected.
This declaration
struct abc *d;
on the one hand declares struct abc
and on the other hand declares pointer d
of type struct abc *
.
In this declaration there is no need to have the exact definition of struct abc because no data member of the structure is used.
This specifier struct abc
is called elaborated type specifier.
It introduces a new type in the given scope or refers to an already declared type.
You're right in that, usually, you'd need a forward declaration of such a type:
// Forward declaration
struct bar;
struct foo
{
bar* d; // only a pointer-to-bar; forward declaration sufficient
};
struct bar
{
int c;
};
However, you are (for some reason) using the antiquated idiom of writing struct
before the type name. (This was required in C but has never been in C++.)
struct foo
{
struct bar* d;
};
struct bar
{
int c;
};
Because you write struct bar
there instead of just bar
, that itself counts as a forward declaration of sorts. The compiler now knows that bar
is a type and that's all it needs to know.
It's a bit obscure and subtle, but that's why you do not need the prior forward declaration any more.
[C++11: 3.1/4]:
[ Note: A class name can also be implicitly declared by an elaborated-type-specifier (7.1.6.3). —end note ]
[C++11: 3.3.2/6]:
The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
for a declaration of the form
class-key attribute-specifier-seqopt identifier
;
the identifier is declared to be a class-name in the scope that contains the declaration, otherwise
for an elaborated-type-specifier of the form
class-key identifier
if the elaborated-type-specifier is used in the decl-specifier-seq or parameter-declaration-clause of a function defined in namespace scope, the identifier is declared as a class-name in the namespace that contains the declaration; otherwise, except as a friend declaration, the identifier is declared in the smallest namespace or block scope that contains the declaration. [ Note: These rules also apply within templates. —end note ] [ Note: Other forms of elaborated-type-specifier do not declare a new name, and therefore must refer to an existing type-name. See 3.4.4 and 7.1.6.3. —end note ]
[C++11: 3.4.4/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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With