Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between these two structure declarations?

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?

like image 480
4daJKong Avatar asked Sep 13 '21 09:09

4daJKong


People also ask

What is the difference between structure declaration and definition?

Declaration means that variable is only declared and memory is allocated, but no value is set. However, definition means the variables has been initialized.

What is declaration in data structure?

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.

What is also called as structure declaration?

Explanation: The structure declaration with open and close braces and with a semicolon is also called structure specifier.

What is the difference between structure declaration and tag?

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.

What is a struct declaration list in C++?

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.

How to hide the declaration of a structure in C++?

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;

Can a struct-declaration-list be repeated?

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.


3 Answers

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; 
like image 175
Some programmer dude Avatar answered Sep 17 '22 16:09

Some programmer dude


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; 
like image 28
DevSolar Avatar answered Sep 18 '22 16:09

DevSolar


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;
like image 29
Vlad from Moscow Avatar answered Sep 19 '22 16:09

Vlad from Moscow