I can't solve next problem:
//foo.h
#ifndef FOO_H_
#define FOO_H_
#include "BAR.h"
#include "foos/foo_bazz.h"
typedef struct
{
...
} FOO;
// HERE I HAVE CALL `foo_baz(foo, bar);`
void
foo_bar(FOO *foo, BAR *bar);
#endif /* FOO_H_ */
//bar.h
#ifndef BAR_H_
#define BAR_H_
typedef struct
{
...
} BAR;
#endif /* BAR_H_ */
//foos/foo_bazz.h
#ifndef FOO_BAZZ_H_
#define FOO_BAZZ_H_
#include "FOO.h"
#include "BAR.h"
void
foo_baz(FOO *foo, BAR *bar);
#endif /* FOO_BAZZ_H_ */
so it makes error like this:
foos/foo_bazz.h: error: unknown type name ‘FOO’; did you mean ‘FOO_H_’?
16 | FOO *foo,
| ^~~~
| FOO_H_
I tried to remove #include "FOO.h" from foos/foo_bazz.h and add typedef struct FOO; or typedef struct FOO FOO; but it didn't make some changes...
Also i tried to make inverse - i declared function in FOO.h, but result is the same.
Help me please, thank you
Why do you want to include foo_bazz in foo.h?
It will fail for sure. The inclusion of the foo.h in foo_bazz.h will not declare the type as it is already protected by the guards.
It makes no sense. Simply include foo_bazz.h in your .c file where you will have function and data definition. IMO X-Y problem.
The problem is that the declaration:
void foo_baz(FOO *foo, BAR *bar);
is encountered before FOO is defined. You can solve that problem by reordering the code in foo.h thus:
#include "BAR.h"
typedef struct
{
...
} FOO;
#include "foos/foo_bazz.h"
void
foo_bar(FOO *foo, BAR *bar);
That said #0___________ 's solution makes more sense in most cases, including this, but it is worth understanding why/how the problem occurred rather than simply blindly fixing it.
Related
I declared a struct in main.c file and i have functions in func1.c func2.c func1.h func2.h files.
main.c:
#include <stdio.h>
#include "func1.h"
#include "func2.h"
struct mystruct{
someting
};
main(){
struct mystruct var ={...};
myfunc(var);
}
func1.h:
void myfunc(struct mystruct);
And definition is in func1.c. Similar for func2 files. I got compilation errors, it is obvious that problem is header file dont have declaration of mystruct and so cant use it.
So what is the way to overcome that problem? Adding a new header file for struct or using extern keyword what i read. What is approprite choice i couldnt figure out at that point.
struct mystruct{
//something
};
Should be defined in a header file which all your c files that need it has access to.
mytypes.h
#ifndef mytypes_h
#define mytypes_h
struct mystruct{
int something;
};
#endif
func1.h
#ifndef func1_h
#define func1_h
#include "mytypes.h"
void myfunc(struct mystruct);
#endif
func1.c
#include "func1.h"
void myfunc(struct mystruct){
//do soemthing with struct
}
Then your main can include func1.h which already mytypes.h
main.c
#include "func1.h"
int main(){
}
I have declared a function in file_utils.h and defined it in file_utils.c At compile time it is gives a conflicting type error.
File_utils.h
#ifndef FILE_UTILS_H
#define FILE_UTILS_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#define NAMLEN(dirent) strlen((dirent)->d_name)
#else
#define dirent direct
#define NAMLEN(dirent) ((dirent)->d_namlen)
#ifdef HAVE_SYS_NDIR_H
#include <sys/ndir.h>
#endif
#ifdef HAVE_SYS_DIR_H
#include <sys/dir.h>
#endif
#ifdef HAVE_NDIR_H
#include <ndir.h>
#endif
#endif
bool is_relative_path(struct dirent *ent);
File_utils.c
#include "file_utils.h"
#include <stdbool.h>
#include <dirent.h>
bool is_relative_path(struct dirent *ent){
return (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0);
}
Error:
abhiram#abhiram-Lenovo-G50-70:~/libpostal-master/src$ gcc -DLIBPOSTAL_DATA_DIR='"$//home/abhiram/libpostal-master/data"' -o main main.c libpostal.c file_utils.c json_encode.c string_utils.c -std=c99 -w
file_utils.c:45:6: error: conflicting types for ‘is_relative_path’
bool is_relative_path(struct dirent *ent){
^
In file included from file_utils.c:1:0:
file_utils.h:59:6: note: previous declaration of ‘is_relative_path’ was here
bool is_relative_path(struct dirent *ent);
^
I have included both dirent.h and stdbool.h libraries.
Resolve all compiler warnings.
Compile with all compiler warnings enabled -Wall -Wextra.
Resolve all compiler warnings.
The code you posted has a missing #endif, maybe probably from #ifdef HAVE_DIRENT_H, but I am guessing the last line of the file_utils.h should be a closing #endif.
The warning I get from gcc is this:
warning: ‘struct direct’ declared inside parameter list
warning: its scope is only this definition or declaration, which is probably not what you want
This is the the most important warning.
Structure definition is only valid inside function parameter list. Ex:
void other_f(
struct B a // this will forward declare struct B
// scope of this variable is _only_ inside function parameter list
); // here struct B get's out of scope!
struct B b; // will error, there is no struct B here
// struct B was declared inside function parameter list
// you can't use it anywhere else
The MCVE to your problem would be this example:
void f(struct A);
struct A;
void f(struct A); // error conflicting types for 'f'
The struct A will be declared (I call it "auto-declared") inside the function parameter list void f( <here> ) on the first use. The structure declaration will be visible only inside the parameter list. So it's similar to a pseudocode:
{
struct A; // type only valid inside `{` `}` braces
void f(struct A a); // imagine this symbol is visible outside `{` `}`
}
ie. the struct A is not visible outside the { }.
Then you declare another struct A:
struct A;
void f(struct A a);
But this struct A is different type as the other struct A. As it's different struct A, the function f is different, the compiler issues an error.
No consider your header:
#define dirent direct
...
bool is_relative_path(struct dirent *ent);
I don't know if direct is a typo or not. But you need to forward declare the struct direct, so that the forward declaration of struct direct is visible outside the function parameter list of is_relative_path function.
struct direct;
#define dirent direct
...
// or here:
struct dirent;
bool is_relative_path(struct dirent *ent);
Your problem seems to be file inclusion order if "File_utils.c" and / or a missing definition of HAVE_DIRENT_H.
In the given inclusion order, "file_utils.h" has no idea what a struct dirent is, since (presumably HAVE_DIRENT_H) is defined within <dirent.h>. If this is NOT the case, simply ensure that HAVE_DIRENT_H IS defined before including "file_utils.h"
The net effect as-is in the code is that in "file_utils.h", bool is_relative_path(struct dirent *ent) is actually seen as bool is_relative_path(some_pointer_to_an_unknown_struct_type ent), while the "file_utils.c" sees the function signature as as bool is_relative_path(a_pointer_to_a_struct_type_i_definately_know_about ent).
Thus the two files do NOT agree on the function signature.
Edit
#n.m. is correct in that "file_utils.h" essentially sees a distinct definition of struct dirent, and that one cannot declare a type inside a function parameter list.
TLDR
Edit File_utils.c to define HAVE_DIRENT_H and / or #include <dirent.h> before #include "file_utils.h" so that both "file_utils.h" and "file_utils.c" see a common function signature for bool is_relative_path(struct dirent *ent)
It looks like the declaration of bool is_relative_path(struct dirent *ent); is AFTER the #endif preprocessor declaration (include guards). That mean including this header file in two different files will cause two declarations. Have a look at this: https://en.wikipedia.org/wiki/Include_guard to get some more details
This should fix it:
#ifndef FILE_UTILS_H
#define FILE_UTILS_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#define NAMLEN(dirent) strlen((dirent)->d_name)
#else
#define dirent direct
#define NAMLEN(dirent) ((dirent)->d_namlen)
#ifdef HAVE_SYS_NDIR_H
#include <sys/ndir.h>
#endif
#ifdef HAVE_SYS_DIR_H
#include <sys/dir.h>
#endif
#ifdef HAVE_NDIR_H
#include <ndir.h>
#endif
// moved the declaration between the #ifndef #endif block
bool is_relative_path(struct dirent *ent);
#endif
You cannot declare a type inside a function parameter list. This is what happens when in File_utils.h you have a declaration of is_relative_path with no prior declaration of stuct dirent.
Either #include <dirent.h> in File_utils.h (recommended), or add a declaration
struct dirent;
somewhere in it above is_relative_path.
I am building a project that I am trying to organize as follows:
main.c
globals.h
structures.h
FunctionSet1.c, FunctionSet1.h
FunctionSet2.c, FunctionSet2.h
etc.
I thought I could define a structure type in structures.h:
struct type_struct1 {int a,b;}; // define type 'struct type_struct1'
then declare a function1() returning a structure of type type_struct1 in FunctionSet1.h:
#include "structures.h"
struct type_struct1 function1(); // declare function1() that returns a type 'struct type_struct1'
then write function1() in FunctionSet1.c:
#include "FunctionSet1.h"
struct type_struct1 function1() {
struct type_struct1 struct1; // declare struct1 as type 'struct type_struct1'
struct1.a=1;
struct1.b=2;
return struct1;
}
Edit: with the corrected code above, the compiler returns
306 'struct' tag redefined 'type_struct1' structures.h
Is the file set good practice ?
What is the good practice to manage the structures ?
In your example, you declare a structure named type_struct in structure.h, then in FunctionSet1.h the structure that you are returning is type_struct, and in the .c it is called struct1.
So i think that the problem is that struct1 and type_struct are not recognized because they have never been defined ...
However, the organization of your files is fine.
Your general structure looks good. One thing you need to do, as zenith mentioned, is to put include guards into your header files. What that is is a set of #define's that make sure that the contents of the header are not included more that once in a given file. For example:
structures.h:
#ifndef STRUCTURES_H
#define STRUCTURES_H
struct type_struct1{
int a,b;
};
...
// more structs
...
#endif
FunctionSet1.h:
#ifndef FUNCTION_SET_1_H
#define FUNCTION_SET_1_H
#include "structures.h"
struct type_struct1 function1();
...
// more functions in FucntionSet1.c
...
#endif
main.c:
#inlcude <stdio.h>
#include "structures.h"
#include "FunctionSet1.h"
int main(void)
{
struct type_struct1 struct1;
struct1 = function1();
return 0;
}
Here, main.c includes structures.h and FunctionSet1.h, but FunctionSet1.h also includes structures.h. Without the include guards, the contents of structures.h would appear twice in the resulting file after the preprocesser is done. This is probably why you're getting the "tag redefined" error.
The include guards prevent these type of errors from happening. Then you don't have to worry about whether or not a particular header file was included or not. This is particularly important if you're writing a library, where other users may not know the relationship between your header files.
First of all, you have to declare the structure in your file.h (you can use typedef to create an alias)
typedef struct Books
{
char title[50];
int book_id;
} books;
then, you have to include your file.h in your file.c and declare your variable like this
#include "file.h"
int main()
{
books book1;
book1.title = "Harry Potter";
book1.book_id = 54;
}
or like this if you didn't use typedef
#include "file.h"
int main()
{
struct Books book1;
book1.title = "Harry Potter";
book1.book_id = 54;
}
Thank you all.
I read again what you said and found that the code above is now correct.
The error I report is with testing the following main.c
#include "structures.h"
#include "FunctionSet1.h"
void main() {
struct type_struct1 struct2;
struct2=function1();
}
in which structures.h is included again, thus causing the error. Removing the include eliminates the error.
I will now look into header guards to avoid such problems.
Thanks again.
Say I have 3 files: file1.c, file2.c and globals.h. file1.c and file2.c both include globals.h. file1.c contains a struct that file2.c needs to use. Is it better to make the struct itself extern or create a pointer to the struct and make that pointer extern in globals.h?
If I understand correctly and your "a struct" is supposed to be a global object (which is a questionable design choice), then I'd do it like this:
foo.h:
typedef struct foo_struct
{
/* ... */
} foo;
extern foo the_foo;
foo.c: [If you like and if it makes sense, you can merge this into file1.c.]
#include "foo.h"
foo the_foo = { /* ... */ };
file1.c and file2.c:
#include "foo.h"
#include "global.h"
/* ... */
I have a list of checkpoints and then a run a function. I originally built this list in that function, but now I have to build it outside. The problem is that I cannot include checkpoint.h in the class that implements that function because checkpoint.h returns a structure of the type of that class. The initial list was declare in class.c globally. How can I transfer the list created outside into class so I can use it?
So I have this header, turing_machine.h:
#ifndef __TURING_MACHINE__
#define __TURING_MACHINE__
#include "tape.h"
#include "alphabet.h"
#include "symbol_table.h"
...
#endif
and the checkpoint.h header defining the checkpoint_list class:
#ifndef __CHECKPOINT_H__
#define __CHECKPOINT_H__
#include "turing_machine.h"
...
#endif
So I want to send to a function from turing_machine.h a list of structures checkpoint but I can't modify anything because that's how the classes must stay.
I have also turing_machine.c:
#include "turing_machine.h"
#include "checkpoint.h"
#include "symbol_table.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
checkpoint_list *c;
So at the beginning I created in turing_machine that list, c, but now I must create it outside and I have to initialize that list c but I don't know how. I hope this is more clear.
I used the term class wrong; I have just .c and .h files.
Reading between the lines, somewhat, I think your trouble is that you have 'mutually referencing' structures.
The way to work around this is with an incomplete type definition:
typedef struct checkpoint_list checkpoint_list;
You can then use that inside turing_machine.h:
#ifndef TURING_MACHINE_H_INCLUDED
#define TURING_MACHINE_H_INCLUDED
#include "tape.h"
#include "alphabet.h"
#include "symbol_table.h"
typedef struct checkpoint_list checkpoint_list;
typedef struct turing_machine
{
...
} turing_machine;
extern checkpoint_list *tm_function(turing_machine *);
extern turing_machine *tm_create(const char *);
#endif
And, inside checkpoint.h, you can write:
#ifndef CHECKPOINT_H_INCLUDED
#define CHECKPOINT_H_INCLUDED
#include "turing_machine.h"
/* No typedef here in checkpoint.h */
struct checkpoint_list
{
...
};
extern checkpoint_list *cp_function(const char *);
extern turing_machine *cp_machine(checkpoint_list *);
#endif
This technique is recognized and defined by the C standard (C90, let alone C99 or C11).
Note that I've also renamed the include guards; names that start with double underscore are reserved for 'the implementation' (meaning the C compiler and its libraries), and you should not invent and use such names in your own code.