I have a code duplication situation where I have exact same body of struct but with different names. The body of struct is not small, hence there is risk of injecting error while modifying code in future. Following is just example to illustrate the problem:
struct read_data_on_disk {
int a;
char b;
};
struct read_data {
int a;
char b;
};
It is possible to define one of them, say read_data_on_disk and another be just defined as alias of it? I am looking for something like below:
typedef struct read_data_on_disk struct read_data; // this is wrong though
That's almost right. Try this:
struct read_data_on_disk {
int a;
char b;
};
typedef struct read_data_on_disk read_data;
But as dbush pointed out above, why have two structs if their content is identical?
Related
Hi I was triying to make something like this, but I cant sort it out. The problem is one typedef needs the other one. I would really appreciate someones help!
#ifndef SHELL_DATA_H
#define SHELL_DATA_H
#include <buffer.h>
#define COMMANDS 10
#define MAX_ARGS 4
typedef struct {
void (*command)(int, char **, t_shellData *shelldData);
char *name;
char *description;
} t_command;
typedef struct {
t_command commands[COMMANDS];
t_buffer buffer;
char username[BUFFER_SIZE];
} t_shellData;
#endif
typedef struct command t_command;
typedef struct shelldata t_shellData;
struct command {
void (*command)(int, char **, t_shellData *shelldData);
char *name;
char *description;
};
struct shelldata {
t_command commands[COMMANDS];
t_buffer buffer;
char username[BUFFER_SIZE];
};
should fix it up for you. The structure tag and typedef name can be the same; I just renamed them for clarity.
C is a simple language, with an underlying principle of do not surprise people. For this reason, entities in C need to be declared or defined before they are used. As a simple example:
int f() {
int a = 7;
int b = a;
....
}
is OK, but this is not:
int f() {
int b = a;
int a = 7;
....
}
and while not exactly, languages like golang permit this -- the compiler will root around and find the definition you obviously wanted.
Typedef, in C, really just puts an entry into the symbol table; it is like a define, but less blunt, so the line:
typedef struct a A;
Serves to inform the compiler of two things: somewhere there is a structure with tag a, and I want A to be a shortform for it. There is another form of this:
struct a;
typedef struct a A;
Here, the first line tells the compiler "I want you to know about a thing called struct a"; and the second line "I want an alias to that struct a thing called A".
So, as the compiler progresses through the source, it knows that an A means a struct a, and even if it hasn't seen the definition of struct a, it has a placeholder.
But, if you attempted, before defining struct a to define another structure:
struct b {
struct a stuff;
int morestuff;
};
The compiler would complain, because it doesn't know the layout of a struct a; however this:
struct b {
struct a *stuff;
int morestuff;
};
is OK, because it knows how big a pointer is, and can defer its understanding of a struct a until it needs it.
So, Summary: declare or define data types before you attempt to use them. The C compiler requires it. A declaration is ok, unless you need the actual layout of it, in which case a definition is required.
Good Luck.
I have a couple of questions. I have a bit of a hard time understanding this code. What exactly is it doing?
For example:
What does typedef struct dynArrStruct do and why does it have dynArr at the end of it? I know the definition of typedef as "allows to created alias for a known data type" but that is jargon to me. Can someone try to put it in layman terms? Thank you!
Why are there 2 struct variables (a1/a2)?
Link to full code if needed:
http://www.cs.uic.edu/pub/CS211/CS211LectureNotesS13/dynArr.c
typedef struct dynArrStruct
{
double *location;
int length;
int currSize;
} dynArr;
int main (int argc, char**argv)
{
struct dynArrStruct a1;
dynArr a2;
int i;
//rest of code
}
What does typedef struct dynArrStruct do and why does it have dynArr at the end of it?
The typedef creates an alias to a type to save you some typing, or to improve readability. In this particular case, it creates an alias called dynArr for the struct dynArrStruct.
Without a typedef, i.e. with only this
struct dynArrStruct
{
double *location;
int length;
int currSize;
};
you would be forced to write struct dynArrStruct every time you need to declare a variable of that struct's type. With a typedef in place, you can write simply dynArr, and the compiler will interpret it as the struct dynArrStruct for you.
typedef struct dynArrStruct
{
double *location;
int length;
int currSize;
} dynArr;
Is a short form of two different pieces of code.
// define a struct by name dynArrStruct
struct dynArrStruct
{
double *location;
int length;
int currSize;
};
//Example of use
struct dynArrStruct d1;
and
// define an alias to "struct dynArrStruct" called dynArr
typedef struct dynArrStruct dynArr;
//Example of use
dynArr d2; //whoa so short!
In addition to dasblinkenlight's answer,
Why are there 2 struct variables (a1/a2)?
The code presented appears to be an example of poorly modularised code (a1) and well modularised code (a2). The modifications made to a1 are very similar to the modifications made to a2. However, the modifications made to a2 are abstracted out into functions (lines 53-55 correspond to the lines found in init, 57-58 correspond to the lines found in push and push), so that that functionality can be easily reused. An example of this reuse is lines 69-72.
I've seen C structs declared several different ways before. Why is that and what, if anything, does each do different?
For example:
struct foo {
short a;
int b;
float c;
};
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
int main (int argc, char const *argv[])
{
struct foo a;
bar b;
baz c;
return 0;
}
Well, the obvious difference is demonstrated in your main:
struct foo a;
bar b;
baz c;
The first declaration is of an un-typedefed struct and needs the struct keyword to use. The second is of a typedefed anonymous struct, and so we use the typedef name. The third combines both the first and the second: your example uses baz (which is conveniently short) but could just as easily use struct _baz to the same effect.
Update: larsmans' answer mentions a more common case where you have to use at least struct x { } to make a linked list. The second case wouldn't be possible here (unless you abandon sanity and use a void * instead) because the struct is anonymous, and the typedef doesn't happen until the struct is defined, giving you no way to make a (type-safe) pointer to the struct type itself. The first version works fine for this use, but the third is generally preferred in my experience. Give him some rep for that.
A more subtle difference is in namespace placement. In C, struct tags are placed in a separate namespace from other names, but typedef names aren't. So the following is legal:
struct test {
// contents
};
struct test *test() {
// contents
}
But the following is not, because it would be ambiguous what the name test is:
typedef struct {
// contents
} test;
test *test() {
// contents
}
typedef makes the name shorter (always a plus), but it puts it in the same namespace as your variables and functions. Usually this isn't an issue, but it is a subtle difference beyond the simple shortening.
It's largely a matter of personal preference. I like to give new types a name starting with a capital letter and omit the struct, so I usually write typedef struct { ... } Foo. That means I cannot then write struct Foo.
The exception is when a struct contains a pointer to its own type, e.g.
typedef struct Node {
// ...
struct Node *next;
} Node;
In this case you need to also declare the struct Node type, since the typedef is not in scope within the struct definition. Note that both names may be the same (I'm not sure where the underscore convention originated, but I guess older C compilers couldn't handle typedef struct X X;).
All your uses are syntactically correct. I prefer the following usage
/* forward declare all structs and typedefs */
typedef struct foo foo;
.
.
/* declare the struct itself */
struct foo {
short a;
int b;
foo* next;
};
Observe that this easily allows to use the typedef already inside the declaration of the struct itself, and that even for struct that reference each other mutually.
The confusion comes about because some of the declarations are in fact declaring up to three C constructs. You need to keep in mind the difference between:
A typedef declaration,
A struct definition, and
A struct declaration.
They are all very different C constructs. They all do different things; but you can combine them into the one compound construct, if you want to.
Let's look at each declaration in turn.
struct foo {
short a;
int b;
float c;
};
Here we are using the most basic struct definition syntax. We are defining a C type and give it the name foo in the tag namespace. It can later be used to declare variables of that type using the following syntax:
struct foo myFoo; // Declare a struct variable of type foo.
This next declaration gives the type another name (alias) in the global namespace. Let's break it down into its components using the previous basic declaration.
typedef foo bar; // Declare bar as a variable type, the alias of foo.
bar myBar; // No need for the "struct" keyword
Now just replace "foo" with the the struct's definition and voila!
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
The above syntax is equivalent to the following sequence of declarations.
struct _baz {
short a;
int b;
float c;
}
typedef _baz baz; // Declare baz as an alias for _baz.
baz myBaz; // Is the same as: struct _baz myBaz;
I am using structs in my project in this way:
typedef struct
{
int str1_val1;
int str1_val2;
} struct1;
and
typedef struct
{
int str2_val1;
int str2_val2;
struct1* str2_val3;
} struct2;
Is it possible that I hack this definition in a way, that I would use only types with my code, like
struct2* a;
a = (struct2*) malloc(sizeof(struct2));
without using keyword struct?
Yes, as follows:
struct _struct1
{
...
};
typedef struct _struct1 struct1;
struct _struct2
{
...
};
typedef struct _struct2 struct2;
...
struct2 *a;
a = (struct2*)malloc(sizeof(struct2));
Yes, you can use the typedef'ed symbol without needing the struct keyword. The compiler simply uses that name as an alias for the structure you defined earlier.
One note on your example, malloc returns a pointer to memory. Hence your statement should read
a = (struct2 *)malloc(sizeof(struct2));
Just to share, I've seen this approach, and though I personally don't like it (I like everything named and tagged =P and I don't like using variable names in malloc), someone may.
typedef struct {
...
} *some_t;
int main() {
some_t var = (some_t) malloc(sizeof(*var));
}
as a footnote. If you code in C++ then you don't need to do the typedef; a struct is a type automatically.
How can I have a pointer to the next struct in the definition of this struct:
typedef struct A {
int a;
int b;
A* next;
} A;
this is how I first wrote it but it does not work.
You can define the typedef and forward declare the struct first in one statement, and then define the struct in a subsequent definition.
typedef struct A A;
struct A
{
int a;
int b;
A* next;
};
Edit: As others have mentioned, without the forward declaration the struct name is still valid inside the struct definition (i.e. you can used struct A), but the typedef is not available until after the typedef definition is complete (so using just A wouldn't be valid). This may not matter too much with just one pointer member, but if you have a complex data structure with lots of self-type pointers, may be less wieldy.
In addition to the first answer, without a typedef and forward declaration, this should be fine too.
struct A
{
int a;
int b;
struct A *next;
};
You are missing the struct before the A*
typedef struct A {
int a;
int b;
struct A* next;
} A;
You can go without forward declaration:
struct A {
int a;
int b;
struct A *next;
};
Please, you're in C, not C++.
If you really must typedef a struct (and most programmers that I work with would not¹), do this:
typedef struct _A {
int a;
int b;
struct _A *next;
} A;
to clearly differentiate between _A (in the struct namespace) and A (in the type namespace).
¹typedef hides the size and storage of the type it points to ― the argument (and I agree) is that in a low-level language like C, trying to hide anything is harmful and counterproductive. Get used to typing struct A whenever you mean struct A.
typedef struct {
values
} NAME;
This is shorter way to typedef a struct i think its the easiest notation, just don't put the name infront but behind.
you can then call it like
NAME n;
NAME *n; // if you'd like a ptr to it.
Anything wrong with this approach?