-1

I am a bit confused when using struct in c/c++. Traditionally, when I use struct, I usually use it as:

typedef struct Name{
    int a;
};

Name var;

Although it is considered a bad practice from Linus, it's somehow common.

Yet, I wonder

struct Name{
    int a;
};
Name var;

Seems to serve the same purpose, is typedef really necessary? In fact, shouldn't it be

struct Name{
    int a;
};
struct Name var;

Why is the struct from "Name" omitted? If it can always be omitted, does that mean typedef struct is totally useless?

anastaciu
  • 23,467
  • 7
  • 28
  • 53
HAO LEE
  • 153
  • 3
  • 13
  • 10
    This is why specifying languages properly is important. The second code block is C++, the others *would* work in both C and C++. They're different languages. The first one should also have a `Name` after the closing `}`, the `typedef` is incomplete there. – Thomas Jager May 10 '22 at 09:49
  • 3
    not sure what Linus would say to applying his guide to C++ :P. Please choose one language. The answers for C and C++ for this specific question will be very different. It seems like you refer to C – 463035818_is_not_an_ai May 10 '22 at 09:57
  • 2
    @Darth-CodeX - That's a misrepresentation. IIRC Linus said it's terrible for *kernel* development. – StoryTeller - Unslander Monica May 10 '22 at 10:13
  • 3
    `typedef struct Name {int a;}` [is a useless `typedef`](https://stackoverflow.com/q/6399898/509868): it doesn't define any new type (your compiler should emit a warning when it sees this). This code is equivalent to `struct Name {int a;}`. Using a useless `typedef` is a common error because "you must use `typedef`" is a common guideline, and a useless `typedef` looks like the most straightforward syntax, even though it does nothing. – anatolyg May 10 '22 at 10:14
  • @StoryTeller-UnslanderMonica I agree, forgot to edit that, `nothing can even come close to C when it comes to kernel dev` – Darth-CodeX May 10 '22 at 10:16
  • Pick one language and delete the other tag. Better, since there are answers already, delete the question. If you still need clarification, post a new question with only one language tag. However, I recommend working completely through a primer or textbook or completing a class in the language before asking elementary questions on Stack Overflow. – Eric Postpischil May 10 '22 at 11:24
  • 1
    You need `#ifdef __cplusplus` / `#error c++ compiler detected` / `#endif` – pmg May 10 '22 at 13:42
  • The `typedef struct Name { ... } Name;` construct in C is so common that when they made C++ they made that implicit. In C++ when you write `struct Name` or `class Name` is defines a type `Name` that you can use without `struct` or `class`. – Goswin von Brederlow May 10 '22 at 17:48

3 Answers3

3

For:

typedef struct Name{
    int a;
};

Name var;

The definition should be:

typedef struct Name{
    int a;
} Name;

Name var;

Otherwise you are not aliasing the type.


In C++ this doesn't make sense, when you declare struct Name you can already instantiate Name omitting the struct keyword, as you do in the second code snippet, which would not work for C. It behaves similarly to class, in this regard, you don't declare class Name var;, just Name var;.

In C I don't agree it's a bad practice, it's a user defined type, why would you always use struct if you can omit it, any programmer worthy of that name should be able to identify a user defined type, it's not rocket science. This though is opinion based. If it's bad practice we will need to revise the whole notion, not only in C++ but also C#, where class and struct keywords are always omitted when instantiating objects.

As for aliasing pointers, I completely agree, I do not like it one bit, though this can also be seen as opinion based.

So to answer your direct questions:

Seems to serve the same purpose, is typedef really necessary?

For the purpose you describe in C yes, in C++ no.

Why is the struct from "Name" omitted?

In C it cannot be ommited, unless you typedefine it, in C++ not only it can, but it should, it's not needed at all.

If it can always be omitted, does that mean typedef struct is totally useless?

As you can see, it's not useless.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
1

Always using struct keyword while initializing a variable could be lengthy (or whatever you think). That's why there's a typedef keyword (although it have many other uses too).

You can declare a struct with typedef like this:

typedef struct{
    int a;
}var;

or

struct Name{
    int a;
};

typedef struct Name var;

Then use it like:

var my_age;

However, the above explanation covers only C, whereas in C++ structs are similar to classes but their members are public by default.

So, in C++ you can directly use the struct's name without typing struct keyword again n again

struct Name {
    int a;
};

Name my_age;
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23
0

In C and C++, rules are different. The code you show is clearly C++, it wouldn’t compile in C.

With the following definitions:

struct Foo {
    /*fields*/
};

typedef struct Bar {
    /*fields*/
} Baz;

in C, variable declarations struct Foo var, struct Bar var, Baz var are valid, but plain Foo var or Bar var are not. In C++ all such variable declarations are valid. Thus, C code would typically look like:

struct Foo {
    /*fields*/
};

typedef struct {
    /*fields*/
} Baz;

struct Foo var1;
Baz var2;

while in C++, the typical form is:

struct Foo {
    /*fields*/
};

Foo var;

UPD: technically, that’s because in struct Foo {..., in C type name is struct Foo; while in C++ the name is simply Foo, and struct is only needed to declare the type, not to use it.

numzero
  • 2,009
  • 6
  • 6