For starters there is no anonymous structure as others have written in their answers to your question. There is an unnamed structure (a structure without a tag name) that has the alias name COMPLEX
typedef struct {
float real;
float imag;
} COMPLEX;
In C++ the term unnamed class/structure is documented like (the C++ 14 Standard, 9 Classes)
A class-specifier whose class-head omits the class-head-name defines
an unnamed class.
As for the notion anonymous structure then it is defined in C the following way (6.7.2.1 Structure and union specifiers, p.#1)
13 An unnamed member of structure type with no tag is called an
anonymous structure; an unnamed member of union type with no tag is
called an anonymous union. The members of an anonymous structure or
union are considered to be members of the containing structure or
union. This applies recursively if the containing structure or union
is also anonymous.
Here is an example of an anonymous structure
struct A
{
struct { int x; int y; }; // <== anonymous structure
int z;
};
Bear in mind that in C++ opposite to C there is no such a notion as anonymous structure. In C++ there is only the notion of anonymous union.
As for your question
Are they both correct? Why? and is it necessary to add the lowercase
of complex before struct? What is general situation?
then the both typedef declarations are correct. And there is no need to use exactly lower-case name complex as the structure tag. You may use also upper-case name COMPLEX as the structure tag.
typedef struct COMPLEX {
float real;
float imag;
} COMPLEX;
In this structure declaration
typedef struct {
float real;
float imag;
}COMPLEX;
there is declared a structure without a tag name. So you can refer it only by means of its alias name COMPLEX
.
In C structure tag names have their own name space that do not conflict with identifier names in other name spaces.
From the C Standard (6.2.3 Name spaces of identifiers)
1 If more than one declaration of a particular identifier is visible
at any point in a translation unit, the syntactic context
disambiguates uses that refer to different entities. Thus, there are
separate name spaces for various categories of identifiers, as
follows:
— the tags of structures, unions, and enumerations (disambiguated by
following any32) of the keywords struct, union, or enum);
For example consider the following program.
#include <stdio.h>
typedef struct {
float real;
float imag;
} COMPLEX;
int main(void)
{
int COMPLEX;
COMPLEX c = { 0.0f, 0.0f };
return 0;
}
The compiler will issue an error because the declaration of the local variable COMPLEX hides the alias name of the unnamed structure declared in the file scope.
However if you will write
#include <stdio.h>
typedef struct COMPLEX {
float real;
float imag;
} COMPLEX;
int main(void)
{
int COMPLEX;
struct COMPLEX c = { 0.0f, 0.0f };
return 0;
}
then the name COMPLEX of the local variable will not conflict with the tag name COMPLEX of the structure. The C compiler can only issue a message that declared variables are not used.
Another important difference is that sometimes you need to refer to the declared structure specifier within the structure definition itself.
For example if you want to declare a singly-linked list in C you need to write
typedef struct Node
{
int data,
struct Node *next;
} Node;
Without the tag name like
typedef struct
{
int data,
struct Node *next;
} Node;
the compiler considers this structure definition as declarations of two different type specifiers: unnamed structure with the alias name Node and another structure with the tag name Node. These types are not compatible.
As for C++ then you may use the name of a structure tag without specifying the keyword struct
For example
struct complex{
float real;
float imag;
};
struct complex c1;
complex c2;
Also you can refer the structure specifier within its definition without using the keyword struct because (the C++ 15 Standard, 9 Classes)
2 A class-name is inserted into the scope in which it is declared
immediately after the class-name is seen. The class-name is also
inserted into the scope of the class itself; this is known as the
injected-class-name.
For example
struct Node
{
int data,
Node *next;
};
But again a declaration of a variable or a function can hide a declaration of a structure. In this case you need to use the keyword struct. Such using of a name with the keyword struct is called in C++ as elaborated type specifier.
For example
struct complex{
float real;
float imag;
};
int complex;
struct complex c;
Without specifying the keyword struct the compiler will issue an error because the declaration of the integer variable hides the declaration of the structure.
Pay attention to that many programmers do not even know that the typedef in C and C++ can be also rewritten like
struct COMPLEX {
float real;
float imag;
} typedef COMPLEX;
typedef
– Angelia