I am confused about these two structures from different tutorials:
typedef struct complex {
float real;
float imag;
} COMPLEX;
typedef struct {
float real;
float imag;
} COMPLEX;
COMPLEX c1;
Are they both correct? Why? and is it necessary to add the lowercase of complex
before struct? What is general situation?
Declaration means that variable is only declared and memory is allocated, but no value is set. However, definition means the variables has been initialized.
A declaration establishes the names and characteristics of data objects used in a program. A definition allocates storage for data objects, and associates an identifier with that object.
Explanation: The structure declaration with open and close braces and with a semicolon is also called structure specifier.
In this article. A "structure declaration" names a type and specifies a sequence of variable values (called "members" or "fields" of the structure) that can have different types. An optional identifier, called a "tag," gives the name of the structure type and can be used in subsequent references to the structure type.
The struct-declaration-listspecifies the types and names of the structure members. A struct-declaration-listargument contains one or more variable or bit-field declarations. Each variable declared in struct-declaration-listis defined as a member of the structure type.
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;
The declaration of a structure type does not set aside space for a structure. It is only a template for later declarations of structure variables. A previously defined identifier(tag) can be used to refer to a structure type defined elsewhere. In this case, struct-declaration-listcannot be repeated as long as the definition is visible.
With the first you can use either the type-alias COMPLEX
or struct complex
.
With the second you have an anonymous structure which can only be used with the type-alias COMPLEX
.
With that said, in C++ any structure name is also a type-name and can be used as a type directly:
struct complex { ... }; complex c1;
typedef struct complex{ float real; float imag; }COMPLEX;
This is a struct complex
which has been typedef'ed to COMPLEX
. You can now use both struct complex c1;
and COMPLEX c1;
. As you tagged this question C++, you can also use complex c1;
as the struct
(and thus, the typedef
to avoid it) is not necessary in C++.
typedef struct { float real; float imag; }COMPLEX;
This is an unnamed struct, typedef'ed to COMPLEX
. You can now use COMPLEX c1;
.
So far for the difference between these two (C) constructs.
As you tagged this question C++, the correct thing to do would be to use the features of the C++ header <complex>
:
std::complex< float > c1;
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;
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