cannot declare struct member within a structure in c - c

I want to declare a structure value in a different structure definition in header file. So I have done the following in header file. But compiler gives me the error message field myStructMember has incomplete type
in A.h header file:
struct My_A{
int value;
};
In B.h header file:
struct My_A; // forward declaration
struct My_B
{
struct My_A myStructMember; // error is here!
int differentValue;
};
Is it possible to declare a struct member within a structure declarations?
EDIT: My_A and My_B are declarated in different header file.
EDIT 2:
When I add include "A.h" in B.h, then it works. Does it make any problem?
In B.h header file:
include "A.h" // added this line insead of forward declaration
struct My_B
{
struct My_A myStructMember; // not any error anymore
int differentValue;
};

Not without # including A.h in B.h (or before B.h every time it is referenced - when the compiler parses My_B otherwise it lacks the information required to determine the size of My_A. You could use a pointer instead, but that gains all the overhead of handling them.
If you are just trying to achieve abstraction / details hiding, then you could change your forward declaration of My_A so that it is now a struct of the correct size (using a char array, for instance). Then you must make sure that nothing includes both A.h and B.h as that will cause a compiler error. Oh, and really make sure you get the size right or weird stuff will happen. There are ways to ensure this is correct using macro assertions.
e.g. make B.h
struct My_A{
char hidden_data[4];
};
struct My_B
{
struct My_A myStructMember;
int differentValue;
};

The error is what it says - you can't use struct until you has it's complete type. You simply don't know its size at that point. Forward declaration won't help here.
Alternatively you can use pointer to struct. Pointer size is known.

Related

Storage size of ' ' isn't know [duplicate]

I'm a bit new to C and I'm having a bit of trouble with a project I'm currently working on. Essentially I have the following files: main.c, alarm.c, alarm.h
I have a struct declaration in alarm.c that looks like:
#define STRLEN 150;
struct alarmparams
{
char time[STRLEN];
char duration[STRLEN];
char snooze[STRLEN];
char port[STRLEN];
};
In main.c I have:
#include <stdio.h>
#include <string.h>
#include "alarm.h"
int main(int argc, char *argv[])
{
struct alarmparams params;
printf("%s, %s\n", params.time, params.duration);
}
And in alarm.h I have:
struct alarmparams;
Right now when I go to compile I get the following error:
error: storage size of ‘params’ isn’t known
I've looked through other posts regarding this error, so I have done a bit of research on this already. I've also tried some of the suggested solutions and it's either I get the exact same error or I got more on top of it. I'm at a lose as to how to fix this.
Is there something I'm missing? Did I declare something incorrectly?
In general should structs be declared in the header file or the c file? Or does it even matter? What's the different between:
struct foo {...};
and
typedef struct foo {...};
struct alarmparams;
is the declaration of an incomplete type. You can create a pointer to an object of this type but you cannot declare an object of this type or take its size until it has been completed. You have to make its complete declaration visible in main.c to declare an object of its type.
If you use the type in both alarm.c and main.c, just declare it in alarm.h and include alarm.h in main.c.
For you second question, the difference between:
struct foo {...};
and
typedef struct foo {...} foo_;
is in the latter case you also declare an alias foo_ for the type name struct foo.
You have to declare the structure in the header file alarm.h.
At the moment, when you include alarm.h, the code in main doesn't see the structure composition, all it sees is struct alarmparams;, so it doesn't know how long it is. How can you allocate space for something that you don't know how much space it takes?
typedef struct foo { ... }; is invalid: typedef expects you to provide an alias for a type. typedef struct foo { ... } foo_t; would be correct.
typedef is a storage class specifier, thus, you can think of it as any other regular declaration. Imagine you want an alias foo for the type bar: just declare a variable of type bar and call it foo. Now, prepend a typedef keyword behind, and you are done. Even complicated typedefs can be easily understood with this simple approach. Since struct foo { ... }; would be an invalid declaration for a variable (no name is provided), so is typedef struct foo { ... };.
In general, declare structures in the header file when you will reuse them in other source files. If you don't plan on doing so, declaring them on the .c file should be fine.
In addition to the other answers, the value of STRLEN must be known at compile time (it most likely is in this case, but just in case).

How to use a linked list with a header file in C?

I have to create a program that performs various functions with a linked list. I must save the functions in a separate file from the main() but then I can't figure out how to include the list in the header file.
I tried different combinations and right now I have this in the linkedList.h file:
typedef struct list_elements* item;
And this in the linkedList.c
typedef struct list_elements{
int value;
struct list_elements *next;
}item
The problem is that when I try to compile the main.c I get the message: "request for member ‘value’ in something not a structure or union" and "request for member ‘next’ in something not a structure or union".
I looked on the suggested textbooks and online but I cannot find an explanation on how to use linked lists with header files?
(The functions work when I tested the whole thing in a single file, so I don't think they are the problem);
You are trying to typedef the same identifier twice as different types.
Remove the first typedef typedef struct list_elements* item; and put the second one in the header linkedList.h, which must be included in linkedList.c.
The declaration from your header defines type item as a pointer to a struct list_elements. The declaration from linkedList.c declares the same name, item, as an alias for type struct list_elements itself. Although this is not inherently wrong, it is certain to be confusing. It does make it wrong for linkedList.c to #include the header file, which ordinarily it would be appropriate for it to do.
You should make all your type declarations in the header file, and include it in both C source files to ensure that they share those declarations. Type declarations include at least typedefs, struct and union declarations, and function prototypes. This is not an exclusive list of things you might want to put in a header.
There is more than one way to do that:
one of them is to define the structures with the functions' prototype you want to use in a .h file, and the code of the functions in a separate .c (with the same prototypes written in the .h file of course), then you are now ready to use the structure in any other .c file by including your header file. e.g:
StType.h
typedef struct Something{
int a;
int b;
}
typedef struct anotherSomething{
int c;
int d;
}
int fct1();
int fct2();
Fct.c
include StType.h;
int fct1()
{
//...
}
void fct2()
{
//...
}
your program.c
include StType.h
int main()
{
Something s;
fct1();
}
I usualy does something like this.

struct in C: Error storage size of 'params' isn't known

I'm a bit new to C and I'm having a bit of trouble with a project I'm currently working on. Essentially I have the following files: main.c, alarm.c, alarm.h
I have a struct declaration in alarm.c that looks like:
#define STRLEN 150;
struct alarmparams
{
char time[STRLEN];
char duration[STRLEN];
char snooze[STRLEN];
char port[STRLEN];
};
In main.c I have:
#include <stdio.h>
#include <string.h>
#include "alarm.h"
int main(int argc, char *argv[])
{
struct alarmparams params;
printf("%s, %s\n", params.time, params.duration);
}
And in alarm.h I have:
struct alarmparams;
Right now when I go to compile I get the following error:
error: storage size of ‘params’ isn’t known
I've looked through other posts regarding this error, so I have done a bit of research on this already. I've also tried some of the suggested solutions and it's either I get the exact same error or I got more on top of it. I'm at a lose as to how to fix this.
Is there something I'm missing? Did I declare something incorrectly?
In general should structs be declared in the header file or the c file? Or does it even matter? What's the different between:
struct foo {...};
and
typedef struct foo {...};
struct alarmparams;
is the declaration of an incomplete type. You can create a pointer to an object of this type but you cannot declare an object of this type or take its size until it has been completed. You have to make its complete declaration visible in main.c to declare an object of its type.
If you use the type in both alarm.c and main.c, just declare it in alarm.h and include alarm.h in main.c.
For you second question, the difference between:
struct foo {...};
and
typedef struct foo {...} foo_;
is in the latter case you also declare an alias foo_ for the type name struct foo.
You have to declare the structure in the header file alarm.h.
At the moment, when you include alarm.h, the code in main doesn't see the structure composition, all it sees is struct alarmparams;, so it doesn't know how long it is. How can you allocate space for something that you don't know how much space it takes?
typedef struct foo { ... }; is invalid: typedef expects you to provide an alias for a type. typedef struct foo { ... } foo_t; would be correct.
typedef is a storage class specifier, thus, you can think of it as any other regular declaration. Imagine you want an alias foo for the type bar: just declare a variable of type bar and call it foo. Now, prepend a typedef keyword behind, and you are done. Even complicated typedefs can be easily understood with this simple approach. Since struct foo { ... }; would be an invalid declaration for a variable (no name is provided), so is typedef struct foo { ... };.
In general, declare structures in the header file when you will reuse them in other source files. If you don't plan on doing so, declaring them on the .c file should be fine.
In addition to the other answers, the value of STRLEN must be known at compile time (it most likely is in this case, but just in case).

Using static on typedef struct

I use the following code a lot in C:
typedef struct
{
int member;
} structname;
Now i'm trying to keep that struct definition local to a particular source file, so that no other source file even knows the struct exists. I tried the following:
static typedef struct
{
int member;
} structname;
but GCC whines because of an illegal access specifier. Is it even possible to keep a struct's declaration private to a source file?
If you declare the typedef struct within a .c file, it will be private for that source file.
If you declare this typedef in a .h file, it will be accesible for all the .c files that include this header file.
Your statement:
static typedef struct
Is clearly illegal since you are neither declaring a variable nor defining a new type.
All declarations are always local to a particular translation unit in C. That's why you need to include headers in all source files that intend to use a given declaration.
If you want to restrict the use of your struct, either declare it in the file in which you use it, or create a special header that only your file includes.
A structure definition is private to a source file unless placed in a shared header file. No other source file can access the members of the struct, even if given a pointer to the struct (since the layout is not known in the other compilation unit).
If the struct needs to be used elsewhere, it must be used only as a pointer. Put a forward declaration of the form struct structname; typedef struct structname structname; in the headerfile, and use structname * everywhere else in your codebase. Then, since the structure members appear only in one source file, the structure's contents are effectively 'private' to that file.
Hernan Velasquez's answer is the correct answer: there are several problems with your code snippet. Here's a counter-example:
/* This should go in a .h if you will use this typedef in multiple .c files */
typedef struct {
int a;
char b[8];
} mystructdef;
int
main (int argc, char *argv[])
{
/* "static" is legal when you define the variable ...
... but *not* when you declare the typedef */
static mystructdef ms;

How to declare a structure in a header that is to be used by multiple files in c?

If I have a source.c file with a struct:
struct a {
int i;
struct b {
int j;
}
};
How can this struct be used in another file (i.e. func.c)?
Should I create a new header file, declare the struct there and include that header in func.c?
Or should I define the whole struct in a header file and include that in both source.c and func.c? How can the struct be declared extern in both files?
Should I typedef it? If so, how?
if this structure is to be used by some other file func.c how to do it?
When a type is used in a file (i.e. func.c file), it must be visible. The very worst way to do it is copy paste it in each source file needed it.
The right way is putting it in an header file, and include this header file whenever needed.
shall we open a new header file and declare the structure there and include that header in the func.c?
This is the solution I like more, because it makes the code highly modular. I would code your struct as:
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
I would put functions using this structure in the same header (the function that are "semantically" part of its "interface").
And usually, I could name the file after the structure name, and use that name again to choose the header guards defines.
If you need to declare a function using a pointer to the struct, you won't need the full struct definition. A simple forward declaration like:
struct a ;
Will be enough, and it decreases coupling.
or can we define the total structure in header file and include that in both source.c and func.c?
This is another way, easier somewhat, but less modular: Some code needing only your structure to work would still have to include all types.
In C++, this could lead to interesting complication, but this is out of topic (no C++ tag), so I won't elaborate.
then how to declare that structure as extern in both the files. ?
I fail to see the point, perhaps, but Greg Hewgill has a very good answer in his post How to declare a structure in a header that is to be used by multiple files in c?.
shall we typedef it then how?
If you are using C++, don't.
If you are using C, you should.
The reason being that C struct managing can be a pain: You have to declare the struct keyword everywhere it is used:
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
While a typedef will enable you to write it without the struct keyword.
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
It is important you still keep a name for the struct. Writing:
typedef struct
{
/* etc. */
} MyStruct ;
will just create an anonymous struct with a typedef-ed name, and you won't be able to forward-declare it. So keep to the following format:
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
Thus, you'll be able to use MyStruct everywhere you want to avoid adding the struct keyword, and still use MyStructTag when a typedef won't work (i.e. forward declaration)
Edit:
Corrected wrong assumption about C99 struct declaration, as rightfully remarked by Jonathan Leffler.
Edit 2018-06-01:
Craig Barnes reminds us in his comment that you don't need to keep separate names for the struct "tag" name and its "typedef" name, like I did above for the sake of clarity.
Indeed, the code above could well be written as:
typedef struct MyStruct
{
/* etc. */
} MyStruct ;
IIRC, this is actually what C++ does with its simpler struct declaration, behind the scenes, to keep it compatible with C:
// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;
Back to C, I've seen both usages (separate names and same names), and none has drawbacks I know of, so using the same name makes reading simpler if you don't use C separate "namespaces" for structs and other symbols.
For a structure definition that is to be used across more than one source file, you should definitely put it in a header file. Then include that header file in any source file that needs the structure.
The extern declaration is not used for structure definitions, but is instead used for variable declarations (that is, some data value with a structure type that you have defined). If you want to use the same variable across more than one source file, declare it as extern in a header file like:
extern struct a myAValue;
Then, in one source file, define the actual variable:
struct a myAValue;
If you forget to do this or accidentally define it in two source files, the linker will let you know about this.
a.h:
#ifndef A_H
#define A_H
struct a {
int i;
struct b {
int j;
}
};
#endif
there you go, now you just need to include a.h to the files where you want to use this structure.

Resources