13

I want to know the actual use of struct tag_name in C programming. Without using the tag_name also i was getting output as with use of tag_name. I want the exact reason behind this process.

For ex:

//With tag_name st1
struct st1 { int x; char c;}x={100,'a'},y={70,'e'};

//Without any tag_name
struct { int x; char c;}x={100,'a'},y={70,'e'};

printf("x.x= %d \t x.c= %c \n",x.x,x.c);   //Output: x.x=100    x.c=a
printf("y.x= %d \t y.c= %c \n",y.x,y.c);   //Output: y.x=70     y.c=e
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
user6677473
  • 169
  • 1
  • 1
  • 8

3 Answers3

17

In the first case :

struct st1 { 
    int x; 
    char c;
} x = {100, 'a'}, y = {70, 'e'};

you declare a type with name struct st1, and you also create two objects, of this type, x and y. So you can create objects of this type whenever you want, like this :

struct st1 obj1;

However in the second case :

struct { 
    int x; 
    char c;
} x = {100, 'a'}, y = {70, 'e'};

you create a struct and two objects, x and y, but you cannot access this struct again. This means that you cannot create any new objects of this type.

Marievi
  • 4,951
  • 1
  • 16
  • 33
  • Why can't we access the struct without tag_name? – user6677473 May 25 '17 at 12:09
  • 5
    @user6677473 exactly because it does not have a tag_name. You can say `struct st1 obj1` but you cannot say `struct obj2`, this is not a valid declaration. – Marievi May 25 '17 at 12:10
  • Without tag_name also we are creating an objects, right? – user6677473 May 25 '17 at 12:10
  • 1
    @user6677473 yes, in your case you have created objects `x` and `y`, but you cannot create new ones. – Marievi May 25 '17 at 12:11
  • Ok, I agree with your point @Marievi. If we initialise structure variables x and c while declaring a structure without tag_name, then we are able to access those variables. If we try to initialise structure variables x and c while defining without tag_name, it is generating an error. – user6677473 May 25 '17 at 12:22
  • @user6677473 Sure! – Marievi May 25 '17 at 12:23
  • In which case we have to go for struct without tag_name with initialisation? – user6677473 May 25 '17 at 12:36
  • @user6677473 in the case you do not need to create any more objects of this type. – Marievi May 25 '17 at 12:37
  • Also C11 `Generic()` doesn't recognize 2 identically defined untagged structures as compatible. Really kind of annoying since it could have been useful for creating multiple parameter generics much more succinctly. – technosaurus Sep 05 '19 at 19:07
11

A struct declaration tells the compiler how a struct looks like and optionally gives that struct a name. If you want to use a struct as a "type" in your code, it requires a name:

struct coordinate {
  int x;
  int y;
};

// Can now be used as a return type:
struct coordinate getCoordinate ( ) { ... }

// Can now be used as an argument:
void drawAtPoint ( struct coordinate point ) { ... }

// Can be used to create new constants or variables:
const struct coordinate kOrigin = { 0, 0 };
struct coordinate lastViewPosition;

Alternatively you can create a nameless struct and explicitly define it to be a new type using a type definition:

typedef struct {
  int x;
  int y;
} coordinate;

// Can now be used as a return type:
coordinate getCoordinate ( ) { ... }

// Can now be used as an argument:
void drawAtPoint ( coordinate point ) { ... }

// Can be used to create new constants or variables:
const coordinate kOrigin = { 0, 0 };
coordinate lastViewPosition;

But if you don't do either one, you cannot use that struct as a type since in C, the type of a struct is defined by its name and not by its data layout.

The following is valid C code:

struct coordinate {
  int x;
  int y;
};

struct coordinate startCoord = { 20, 80 };
struct coordinate endCoord = startCoord;

Yet the following is not:

struct {
  int x;
  int y;
} startCoord = { 20,  80 };

struct {
  int x;
  int y;
} endCoord = startCoord;

Compiler will fail with an error. It seems as if startCoord and endCoord have the same type in both examples, but that's not true. Two structs don't denote the same type just because they have an equal memory layout or equal field names. For a C compiler, startCoord and endCoord have different types in the later example and thus you cannot assign them as shown above as this requires that both of them have the same type.

So the only situation where you can skip naming your structs is when you directly declare variables of that struct type and there is no requirement to ever refer to that struct again as a data type throughout your code.

Mecki
  • 125,244
  • 33
  • 244
  • 253
1

If you use the tag, you can create more variables of type struct st1 (or types derived from that (e.g., struct st1*)) later:

struct st1 z, *zp;

while after:

struct { int x; char c;}x={100,'a'},y={70,'e'};

you can never create variables of this type ever again.

While you can do:

struct { int x; char c;} z = {80, 'f'}; 
//same layout and member names

it will have a type that's different from that of x's and y's as far as aliasing and type checking is concerned.

The tag allows you to reuse the type.

(Typedefing an anomyous struct

typedef struct { int x; char c;} st1;
st1 x,y,z;

is another way to reuse the type.)

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 1
    +1 for the typedef of anonymous struct -- is there any more to that point? Why two different methods -- is there a case where we'd not want to have a type defined and yet still reuse the struct? – DatuPuti Apr 10 '19 at 19:25
  • 1
    @DatuPuti Usually you don't want unembedded anon structs. Occasionally you may find some use for them (offset size/testing, testing if an integer is an integer constant expression by trying to use it as a bitfield width (you need a struct to have a bitfield)), but it's rare. – Petr Skocik Apr 10 '19 at 19:37