This question already has answers here:
Is it optional to use struct keyword before declaring a structure object?
(3 answers)
Closed 2 years ago.
I tried typing the following code in a simple C project, but it keeps saying that MyStruct is undefined – unless I add struct before every MyStruct (i.e. struct MyStruct my_struct; which just feels wrong?).
struct MyStruct {
int my_int;
}
int main() {
MyStruct my_struct;
my_struct->my_int = 1;
return 0;
}
It’s not wrong, it’s the way C works. Type name is struct MyStruct (it would be simply MyStruct in C++). If you feel that inconvenient, make a typedef, like:
typedef struct MyStruct { ... } MyStruct;
That may or may not be considered a good practice, though.
Also note that a struct (but not a typedef) and a function can have the same name (without the struct prefix). sigaction is a real-word example of that.
Related
This question already has answers here:
Is it a good idea to typedef pointers?
(15 answers)
Closed 4 years ago.
typedef struct llist {
int valor;
struct lligada *prox;
} *LInt;
So this is how linked lists are implemented in C at my university and I have been wondering why in the last line they put a pointer to LInt instead of just LInt.
typedef struct lligada {
int valor;
struct lligada *prox;
} LInt;
Wouldn't this be simpler? I mean it's this last example that I see in tutorials around the web and if we want a pointer to the struct we would just write something like
LInt *foo = ...;
What confuses me is that they declare the pointer in the struct and in the exercises they still do the declaration above. Is there any special reason for this? Is this normal? They also do this for binary trees.
typedef struct llist {
int valor;
struct lligada *prox;
} *LInt;
makes LInt equivalent to struct llist* (with the star included).
This practice of typedefing pointers is pretty much discouraged in all modern resources
on C I've come across but it has been used historically, notably the lcc compiler
uses this practice a lot (their convention capitalizes the pointer typedefed name as well).
The problem with typedefing pointers is that it's potentially confusing and
you can suddenly pass 0 (as NULL) with a special value through them, however if you
have a naming convention (such as capitalizing each pointer typedef) then
the star is effectively not hidden but just expressed as an upper case letter,
although it might still be confusing to someone foreign to your codebase.
So to summarize, with
typedef struct llist {
int valor;
struct lligada *prox;
} *LInt;
you'd then use it like so:
LInt foo = NULL;
whereas without the star in the typedef, the above would be:
LInt *foo = NULL;
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
In C, a struct can be defined, typedefed, and declared as such:
typedef struct {
int bar;
} Foo;
Foo foo;
Or:
struct Foo {
int bar;
} foo;
typedef struct Foo Foo;
I think this is a bit inconsistent and overly verbose. I would like for it to work as in C++.
In C++, you don't need to specify typedef struct Foo Foo; to be able to declare a struct like Foo foo; instead of struct Foo foo;. Why hasn't this been introduced to the C standard, or as a compiler flag option? Are there any examples of C code that would break if typedef struct were to be made optional in C?
It is optional.
struct mystruct {
int x;
};
struct mystruct y;
The struct definitions are in a separate namespace for "tag" names. This is so they don't collide with function or variable names, so you can do things like this:
struct stat st;
int r = stat("/path/file.txt", &st);
You notice how stat is the name of a function and the name of a struct, but they don't collide? This is a real example, see stat (2). If you eliminated this, old code would fail to compile. The typedef creates a name in the same namespace as functions and variables.
struct stat { ... };
int stat(const char *path, struct stat *buf);
typedef struct stat stat; // ERROR
Some style guides advocate not using typedefs, and simply typing struct stat everywhere. Whether or not you agree with this, it is existing practice in various places (such as the Linux kernel!) and the C standards committee is opposed to breaking existing C code bases.
In C++, compatibility with C code is maintained by making struct optional, but if you define a function with the same name as a struct you will need to use struct explicitly in variable definitions:
stat st; // error! stat is a function
struct stat st; // Ok
int r = stat("/path/file.txt", &st);
Well, you have this:
struct Foo {
int bar;
} foo;
typedef struct Foo Foo;
In the first line you are defining the identifier Foo within the struct name space (not in the C++ sense). You can use it and define variables or function arguments of the newly defined type by defining the type of the argument as struct Foo:
void f(struct Foo argument);
In the function above, struct is required.
The second line adds a type alias Foo in the global name space and thus allows you to just write:
void f(Foo argument);
In the function declaration above, struct keyword is no longer needed. Note that since both identifier name spaces are different, defining Foo both in the structs and global spaces is not an error, as it is not redefining the same identifier, but rather creating a different identifier in a different place.
To make the difference clearer:
typedef struct Foo {
int x;
} Bar;
void Foo() { } // correct
//void Bar() {} // error: symbol Bar already defined as an alias to 'struct Foo'
You can define a function with the same name of the struct as the identifiers are kept in different spaces, but you cannot define a function with the same name as a typedef as those identifiers collide.
So, the common idiom is using both:
typedef struct Foo {
int bar;
} Foo;
Foo foo;
Edit (more informations):
In C++, it is slightly different as the rules to locate a symbol have changed subtly. C++ still keeps the two different identifier spaces, but unlike in C, when you only define the symbol within the class identifier space, you are not required to provide the struct/class keyword. What changes are the search rules, not where the identifiers are defined. The compiler will search the global identifier table and after 'Foo' has not been found it will search for 'Foo' within the class identifiers.
Compilers are free to make extensions but since no compiler has made
it the committee has no reason to standardize it.
Are there any examples of C code that would break if typedef struct
were to be made optional in C?
Plenty. Consider something like that:
struct Foo {
int bar;
/* ... */
};
void Foo(void) {
/* ... */
}
It will stop compiling.
In C, is there any effective difference between declaring a struct as
typedef struct {...} Foo;
and
struct Foo {...};
I know the second requires you to prefix uses with struct, but what are the differences between these two definitions that I'll notice when writing or executing the program? What about with enums?
Update: please see comments attached to answer for clarification.
Original post.
Besides having to write "struct" everywhere, something else of note is that using a typedef will allow you to avoid subtle syntax errors when working with pointers:
Quote:
Typedefs can also simplify declarations for pointer types. Consider
this:
struct Node {
int data;
struct Node *nextptr;
};
Using typedef, the above code can be rewritten like this:
typedef struct Node Node;
struct Node {
int data;
Node *nextptr;
};
In C, one can declare multiple variables of the same type in a single
statement, even mixing pointer and non-pointers. However, one would
need to prefix an asterisk to each variable to designate it as a
pointer. In the following, a programmer might assume that errptr was
indeed a Node *, but a typographical error means that errptr is a
Node. This can lead to subtle syntax errors.
struct Node *startptr, *endptr, *curptr, *prevptr, errptr, *refptr;
By defining a Node * typedef, it is assured that all the variables
will be pointer types.
typedef struct Node *NodePtr;
...
NodePtr startptr, endptr, curptr, prevptr, errptr, refptr;
If you write
typedef struct {...} foo;
It saves you from having to write struct foo everywhere: you can just write foo.
(You get this notational convenience for free in C++ by the way).
I would look at this SO question and then summarize that there is no appreciable functional difference between struct { ... } and typedef struct { ... } although the latter may make your code less cumbersome and easier to understand if used correctly.
This question already has answers here:
typedef struct vs struct definitions [duplicate]
(12 answers)
Closed 10 years ago.
Such as:
typedef struct _cairo_clip cairo_clip_t;
Why not directly use _cairo_clip? See numerous similar definitions in some code.
The idea behind typedef is to let you skip the struct keyword. Unlike C++, C does not let you do this:
struct _cairo_clip {
int a;
float b;
};
_cairo_clip cc; // Not allowed
struct _cairo_clip cc; // Allowed, but requires a keyword
If you tried to directly use _cairo_clip, you would need to call it struct _cairo_clip.
struct _cairo_clip is more verbose than cairo_clip_t.
Using a typedef also provides some abstraction, because it means that cairo_clip_t can be implemented as either a built-in type or as implemented as a struct, without causing a change in the syntax of the client code.
This question already has answers here:
Understanding typedef with struct [duplicate]
(6 answers)
Closed 5 years ago.
I have few questions connected with struct and typedef, there is piece of code and I have marked some places where I'm not sure if the syntax is correct. I use Eclipse editor and it shows me when there is problem in compilation. I just don't understand why is sometimes keyword struct needed and sometimes not. I may have also some mistakes of using this keyword. So plese help me to understand it.
let's have struct
typedef struct player
{
char *name;
int gameId;
int points;
int socketfd; //socket descriptor of player
int state;
} player_struct;
lets have another struct
#define PLAYERSLEN 2
typedef struct game{
struct player_struct *players[PLAYERSLEN]; //PLACE1
//some code
} game_struct;
let's have function
player_struct *create_player() //PLACE2
{
player_struct *player; //PLACE3
//alokace pameti
player = (player_struct *) malloc(sizeof(player_struct)); //PLACE4
//PLACE5
player->gameId = -1;
player->points = 0;
player->state = 0;
return player;
}
let's have function? In fact what does this definition mean?
void *( player_struct *player) //PLACE6
{
//some code
}
Questions references:
PLACE1 - is this correct? why can't I use just player_struct *players[PLAYERSLEN]; ??
PLACE2 - it looks like there is not needed struct before player_struct , is it correct? why?
PLACE3 - it looks like there is struct also not needed, is it correct? why?
PLACE4 - it looks like there is struct also not needed, is it correct? why?
PLACE4 & PLACE5 I may should handle errors there, cause there is malloc so I should probably put all the line with PLACE4 to if and if the malloc fails I should put at PLACE 5 free(player). Am I right?
PLACE6 what could have mean this function or whatever it is? The code inside brackets which is not included here should delete the player .. I just don't understand the syntax of wrote function - what does it mean?
PLACE6 - again similar as previous why is not necessary put the keyword struct before player_struct at this line? is it correct?
Really thanks you for your time.
You're doing two things in the initial definition:
You're defining the structure with the type name struct player.
You're creating a typedef called player_struct, which is just an alias for struct player.
As such, either struct player or player_struct is correct (and more-or-less equivalent), but struct player_struct refers to a completely separate type, and is probably incorrect unless you're trying to confuse people.
Now, handling your six cases in order:
PLACE1: As noted above, this code is actually wrong as it stands.
PLACE2, PLACE3, PLACE4: All correct; see above for an explanation.
PLACE5: Yes, you should probably check that player != NULL here just to be sure.
PLACE6: Again, this is correct, and the reason why is above. I'm not sure what void *(...) is supposed to be, though -- if * is actually a function name then it's probably fine though.
It's because the labels are in two separate namespaces (yes, even in C). There's a special namespace for structs.
I like to declare the label in both namespaces, using this:
typedef struct mon_struct {
int a;
} mon_struct;
then you can use either/both struct mon_struct mon = ... or just mon_struct mon = ....
Update
If you want to use just one label, then you can use one of the following:
struct mon_struct { int a; };
// requires namespace resolution using struct tag:
void f(struct mon_struct p);
// -= OR =-
// slightly awkward declaration
typedef struct { int a; } mon_struct;
// but the type exists in the global namespace,
// so we don't need to use the struct tag:
void f(mon_struct p);
but this becomes messy if you are using the struct in both C and C++, particularly when the declaration or implementations move between C and C++ translations without proper guarding (extern "C" { ...stuff... }).
so you might opt to declare it in both namespaces to minimise breakage:
typedef struct mon_struct { int a; } mon_struct;
void f(struct mon_struct p); // << ok
void f2(mon_struct p); // << ok
No. player_struct is a typedef for struct player. You don't need the struct keyword in this case.
Correct. You created a type definition called player_struct which means struct player.
Same reason as 2.
Same reason as 2 & 3.
Yes, you should check to see if malloc() returns NULL. In addition, don't cast the return value from malloc(). Doing so can hide #include errors.
That's not a valid function definition. You don't need struct because of the typedef - same as above.
You may find this all makes more sense if you remove the words typedef, player_struct, and game_struct from your code entirely. Then once you get used to how that all works, you can reintroduce the typedefs and maybe cut down on some typing. As a quick example, you can break down your first definition into its components:
struct player
{
char *name;
int gameId;
int points;
int socketfd; //socket descriptor of player
int state;
};
typedef struct player player_struct;
Maybe that will help you make sense of it?
You don't need struct in PLACE1... as long the definition of player_struct is known, ie, declared before it, or from a .h before it.