I try to do this in C :
typedef struct s_match_fptr
{
char *str;
int (*funcptr)(t_client *client, char **command);
} t_match_fptr;
typedef struct s_client
{
int socket_fd;
int port;
char *server_ip;
struct sockaddr_in s_in;
t_match_fptr *db;
} t_client;
The point is I try to declare a function pointer that takes in parameter a t_client struct in my t_match_ptr struct.
Also, my struct t_client have an array of t_match_ptr.
For simplify, A need to be declared after B AND B needs to be declared after A.
So, is there a way to "predeclare" t_client before the declaration of t_match_ptr?
Thank you and sorry for bad english.
Forward declaration.
Add at the beginning: typedef struct s_client t_client;
Now the compiler will know the type t_client when encountered in s_match_fptr.
Note, the type must be used only by reference in the s_match_fptr definition (i.e. using a pointer). This way the compiler doesn't need to know the actual contents of the type when parsing the code.
Related
I have a problem with some of my functions. I want to get a member ob a struct, out of another struct. The normal call is functionel, but embedded in a function, it doesn't work. Is there any idea why and how I can solve that?
The following function is an example. It should get the time out of a struct, embedded in another struct via the time-converting function "FUN_1"
FUN_1((time_t *)&ptr_to_s_20b_parse_entries->s_28b_meta->time_c);
My structs are:
struct s_28b_meta {
int version;
__time32_t time_c;
__time32_t time_m;
uint32_t i_next;
int hash_value;
int len_database_name;
int *ptr_database_name;
};
struct s_20b_parse_entries {
int *s_28b_meta;
int *s_8b_keys;
int **a_db_entries;
size_t n_db_entries;
int i_next;
};
The decleration:
struct s_28b_meta *ptr_temp;
struct s_20b_parse_entries *ptr_to_s_20b_parse_entries;
In struct s_20b_parse_entries, you have the s_28b_meta field defined as int *. This is not a pointer to struct so you can't use the -> operator on it, which is why you're getting the error.
It should be defined as a struct s_28b_meta *.
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'm trying to figure out how exactly forward declarations interact. When forward declaring a function that takes a typedef'd struct, is there a way to just get the compiler to accept a previously forward declared (but not actually defined) struct as a parameter?
The code that I've got working:
typedef struct{
int year;
char make[STR_SIZE];
char model[STR_SIZE];
char color[STR_SIZE];
float engineSize;
}automobileType;
void printCarDeets(automobileType *);
What I wish I could do:
struct automobileType;
void printCarDeets(automobileType *);
//Defining both the struct (with typedef) and the function later
I feel like I'm either missing something really basic or not understanding how the compiler deals with forward declarations of structs.
Typedefs and struct names are in different namespaces. So struct automobileType and automobileType are not the same thing.
You need to give your anonymous struct a tag name in order to do this.
The definition in your .c file:
typedef struct automobileType{
int year;
char make[STR_SIZE];
char model[STR_SIZE];
char color[STR_SIZE];
float engineSize;
}automobileType;
The declaration in your header file:
typedef struct automobileType automobileType;
void printCarDeets(automobileType *);
I am studying structures in C from K&R book and encountered this:
struct{
int len;
char *str
} *p;
I am confused by this, because where the name of the struct variable should be, they have given a pointer *p. Can anyone please help me here? What does this declaration mean?
This declaration is a pointer to a struct which is composed of 2 fields — an int and a char*. This struct doesn't have a name and if you want to declare another pointer of the same struct, you will have to write it again.
Notice you can write something like this:
struct MyStruct {
int data1;
char data2;
};
This will define a new struct type which you can use later like this to declare a variable: struct MyStruct myVar;. The difference from what you wrote is that this struct doesn't declare a new variable but a new type since the struct in my example has a name and yours does not.
Another option is to use a typedef and give this struct a name and then you can use the name you have given it to declare more variables of that type.
You can read more about it at http://en.wikipedia.org/wiki/Typedef in the "Simplifying a declaration" section.
Im a NOOB with programming and Im really stumped. I get "array type has incomplete element and field 'status' has incomplete type" errors when i compile this code. I have this linked with another pile of code "which is thankfully error free". the errors are identified in this section so any help will be appreciated.
Thank you. here's the C code
struct name;
struct book;
struct Library{
struct Book collection[100];
struct person patrons[100];
int totalBooks;
int totalPatrons;
};
struct person{
char first[32];
char last[32];
enum Stat status;
};
struct Book{
char title[32];
char author[32];
int id;
int year;
int status;
};
enum Stat{ACTIVE=1, INACTIVE=2, CHECKED_OUT=3, CHECKED_IN=4, UNDER_REPAIR=5, LOST=6};
~
Looks like you've come from a C background - unfortunately it isn't valid C# code.
Arrays are defined as char[] first; (also size isn't relevant at this point)
Enums do not need an enum prefix when defining the variables. Same with structs.
You don't need to declare structs for name and book
In fact, I think you're probably wanting to use a string variable instead of char arrays.
struct Library{
Book[] collection;
Person[] patrons;
};
struct Person{
string first;
string last;
Stat status;
};
struct Book{
string title;
string author;
int id;
int year;
int status;
};
enum Stat{ACTIVE=1, INACTIVE=2, CHECKED_OUT=3, CHECKED_IN=4, UNDER_REPAIR=5, LOST=6};
There are basically two things wrong with the section of code you showed that the compiler is complaining about:
C is case sensitive: struct book and struct Book are two different types.
In C, you cannot refer to a type until it has been declared; that is, you cannot define a field of type enum Stat before you define enum Stat.
The actual problem, then, is that the compiler doesn't know what a struct Book is at the point where you try to define an array of them. Similarly, it doesn't know what an enum Struct is at the point where you define a field of that type.
(Mostly unimportant tangent: The reason you are getting the "incomplete type" errors instead of something slightly more useful is because the compiler allows you, in certain cases, to use struct types that you don't actually have the full definition of, but only if you use them through so-called "opaque" pointers (that is, you never actually use the type, you just pass pointers to them around.) In your case you are telling the compiler you want an array of struct Book, which requires a completely define type, which you don't have.)
To fix it you just need to reorder your type definitions so that none of them are used before they're defined, and use consistent casing throughout. Also, while it's legal to continue to refer to struct foo and enum bar in the rest of your program, most people would create a typedef (basically, type aliases) instead. For example:
typedef enum tagStat {
ACTIVE=1,
INACTIVE=2,
CHECKED_OUT=3,
CHECKED_IN=4,
UNDER_REPAIR=5,
LOST=6
} Stat;
typedef struct tagPerson {
char first[32];
char last[32];
Stat status;
} Person;
typedef struct tagBook {
char title[32];
char author[32];
int id;
int year;
int status;
} Book;
typedef struct tagLibrary {
Book collection[100];
Person patrons[100];
int totalBooks;
int totalPatrons;
} Library;
It looks like you are trying to use the Stat enum in your definition of person before you declare/define it. Add enum Stat; where you have the struct statements at the top of the file.