I'm writing this awesome application, at least I think it awesome, in C with the magnificent blend of GObject and after a while I start getting this very, extremely strange error. I also believe to have noticed it not appearing always. However this might just be the IDE's fault. Anyhow...
GCC, apparently, complains: expected ')' before '*' token; this happens in a header file.
This is that very same header file.
#pragma once
#include "global.h"
#include "CharcoalApp.h"
GtkListStore *WebsitesListStore;
// that error is reported for this line
void charcoal_websites_list_initialize(CharcoalApp *app);
As far as I can see, this comes from the CharcoalApp *app parameter for that function.
Because I cannot really understand why this error is happening, I'll include the CharcoalApp.h file. global.h is a very simple header file that carries the main dependencies, mainly GLib, GObject, GThread, GTK+, WebKit and other.
CharcoalApp.h
#ifndef __CHARCOAL_APP_H__
#define __CHARCOAL_APP_H__
#include "global.h"
#include "CharcoalDB.h"
#include "CharcoalWindow.h"
#include "CharcoalWebsitesList.h"
G_BEGIN_DECLS
#define CHARCOAL_TYPE_APP (charcoal_app_get_type())
#define CHARCOAL_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHARCOAL_TYPE_APP, CharcoalApp))
#define CHARCOAL_APP_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHARCOAL_TYPE_APP, CharcoalApp const))
#define CHARCOAL_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHARCOAL_TYPE_APP, CharcoalAppClass))
#define CHARCOAL_IS_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHARCOAL_TYPE_APP))
#define CHARCOAL_IS_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHARCOAL_TYPE_APP))
#define CHARCOAL_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHARCOAL_TYPE_APP, CharcoalAppClass))
typedef struct _CharcoalApp CharcoalApp;
typedef struct _CharcoalAppClass CharcoalAppClass;
typedef struct _CharcoalAppPrivate CharcoalAppPrivate;
struct _CharcoalApp {
GObject parent;
CharcoalAppPrivate *priv;
GtkBuilder *ui;
CharcoalDB *db;
// toplevels
GtkWidget *CharcoalWindow;
};
struct _CharcoalAppClass {
GObjectClass parent_class;
};
GType charcoal_app_get_type(void) G_GNUC_CONST;
CharcoalApp *charcoal_app_new(void);
void charcoal_app_quit(CharcoalApp *app);
G_END_DECLS
#endif /* __CHARCOAL_APP_H__ */
Thank you for your help!
CharcoalApp is not declared in global.h. Suppose you are including CharcoalApp.h in your C file:
CharcoalApp.h is read up to #include "global.h"
global.h is included
Error: expected ')' before '*' token
You should rearrange your header files properly or use a forward declaration (although I don't think is needed in this case).
There are many solutions:
the proper way: include CharcoalApp.h from global.h, not the reverse;
move typedef struct _CharcoalApp CharcoalApp; before `#include "global.h" in CharcoalApp.h;
remove #include "global.h" from CharcoalApp.h and include them in the proper order (global.h last).
I'm not sure if it's obvious to everyone, but I should add that the reason it's complaining (I think) is because it doesn't understand that CharcoalApp is a type name at the time that it's parsing that code (I've seen similar compile-time errors many times in the past). I think it is handling it as a parameter name instead of a parameter's type name, so it expects the end of the argument list (or a comma) instead of another parameter name without a comma.
How about:
#pragma once
#include "global.h"
//#include "CharcoalApp.h"
struct CharcoalApp;
GtkListStore *WebsitesListStore;
// that error is reported for this line
void charcoal_websites_list_initialize(CharcoalApp *app);
Its not exactly pretty, but removing header includes inside other headers and replacing them with forward declarations is something I was taught once and always try to do.
It reduces the amount of time I spend swearing at the compiler over cyclic dependancy significantly, and it also keeps build times down when changing a commonly included header file.
: D
Looks to me like GtkListStore is not defined.
Try changing your code to:
struct _CharcoalApp {
GObject parent;
CharcoalAppPrivate *priv;
GtkBuilder *ui;
CharcoalDB *db;
// toplevels
GtkWidget *CharcoalWindow;
};
struct _CharcoalAppClass {
GObjectClass parent_class;
};
typedef struct _CharcoalApp CharcoalApp;
typedef struct _CharcoalAppClass CharcoalAppClass;
typedef struct _CharcoalAppPrivate CharcoalAppPrivate;
When you uttered the typedef, the underlying structure type wasn't defined yet, and this MIGHT have confused something.
I normally just write something like:
typedef struct {
GObject parent;
CharcoalAppPrivate *priv;
GtkBuilder *ui;
CharcoalDB *db;
// toplevels
GtkWidget *CharcoalWindow;
} CharcoalApp;
Related
I keep running into an issue while trying to include an enumeration from one header file in antoher.
The environment I am working in is embedded C using IAR Embedded Workbench.
I have a header file for dedicated enumerated types named "enums.h"
#ifndef ENUMS_H_
#define ENUMS_H_
typedef enum
{
SET,
SCHEDULE,
EXECUTE
}action_type_t;
#endif
and a header file for a parser named "parser.h"
#ifndef PARSER_H_
#define PARSER_H_
#include "enums.h"
#include <stdint.h>
typedef struct
{
action_type_t action;
uint16_t nbytes;
}Message;
#endif
In parser.c I include the header as
#include "parser.h"
When I compile this, I get the error "identifier action_type_t is undefined"
What am I doing wrong here? I am stumped at this point.
Thank you
Your enum definition is missing commas, your parser.h uses uint16_t while having failed to include <stdint.h> and, to be extra pedantic, your include guard macro is encroaching on the reserved namespace because it starts with _ and a capital letter.
This should work:
enums.h:
#ifndef ENUMS_H_
#define ENUMS_H_
typedef enum
{
SET,
SCHEDULE,
EXECUTE, /*the last comma is optional*/
}action_type_t;
#endif
parser.h:
#ifndef PARSER_H_
#define PARSER_H_
#include "enums.h"
#include <stdint.h>
typedef struct
{
action_type_t action;
uint16_t nbytes;
}Message;
#endif
Thank you to all who answered, I figured I would come back and close this one.
It turns out I had an identically named, but empty header file included in my project...
Next time i'll be better about looking in my own backyard first before asking others.
However PSkocik did provide a working example, and his code compiles perfectly for anyone who stumbles into this thread!
I need to build a "social network" for college, but I always get unknown type name 'List' while compiling. I removed a lot of functions from my headers, but I still get the same error and I don't know why.
I've got 3 headers:
My friend's header
#ifndef FRIEND_H
#define FRIEND_H
#include "ListHeadTail.h"
typedef struct Friend{
int id;
struct Friend *nextFriend;
}Friend;
void printFriends(List *l);
void removeFriend(List *l);
void addFriend(List *l);
#endif /* FRIEND_H */
My list header:
#ifndef LISTHEADTAIL_H
#define LISTHEADTAIL_H
#include "Student.h"
typedef struct pStudent{
struct pStudent *ant;
Student *s;
struct pStudent *prox;
}pStudent;
typedef struct list{
pStudent *head;
pStudent *tail;
}List;
void startList(List *l);
void printList(List *l);
void freeList(List *l);
#endif /* LISTHEADTAIL_H */
My student's header
#ifndef STUDENT_H
#define STUDENT_H
#define MAX 51
#include "Friend.h"
#include "ListHeadTail.h"
typedef struct Student{
int id;
char name[MAX];
Friend *friends;
}Student;
Student* readStudent ();
void printStudent(Student* a);
void changeData(List *l);
#endif /* STUDENT_H */
My main:
#include <stdio.h>
#include <stdlib.h>
#include "ListHeadTail.h"
#include "Friend.h"
#include "Student.h"
int main(int argc, char** argv) {
List l;
startList(&l);
freeList(&l);
return (EXIT_SUCCESS);
}
Thanks for reading.
Here's the (first) error I get when I try to compile this set of files:
$ cc main.c
In file included from main.c:4:
In file included from ./ListHeadTail.h:4:
In file included from ./Student.h:6:
./Friend.h:11:19: error: unknown type name 'List'
void printFriends(List *l);
Look at the file names and line numbers. Note that at ListHeadTail.h line 4, you've already defined LISTHEADTAIL_H, but you haven't yet reached the actual declaration of List. You then go into Student.h, and from there into Friend.h. That includes ListHeadTail.h again -- but since LISTHEADTAIL_H is already defined, this include does nothing. So you continue through Friend.h with no declaration of List, and therefore get an error on the declarations that reference it.
As noted by #lurker in their comment, the basic issue here is circular dependency, and a simple fix is forward declaration. In this case, you could simply modify Friend.H, replacing #include "ListHeadTail.h" with typedef struct list List;.
But to me this is a bit hacky. If you shift the order of includes somewhere, the build might break again.
I think the real problem is that the declarations of the functions (printFriends, etc.) don't belong in Friend.h; they belong in ListHeadTail.h. The functions have nothing to do with the Friend type. Sure, they have "Friend" in their names, but the only type referenced in the declarations is List. So they belong in ListHeadTail.h. Same goes for the changeData function in Student.h.
In an object-oriented design (say, in Java), these functions would all probably be methods of the List class, and would be declared in that class's source file.
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.
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.
I'm just getting started with modular programming in C. I think I'm doing something wrong with the inclusions, because I'm getting a lot of conflicting types for 'functionName' and previous declaration of 'functionName' was here errors. I did put inclusion guards in place.
Do you know a clear tutorial that explains modular programming in C, especially how the inclusions work?
Update: I have tried to isolate my issue. Here's some code, as requested.
Update 2: updated code is below. The errors have been updated, too.
/*
* main.c
*/
#include <stdio.h>
#include "aStruct.h"
int main() {
aStruct asTest = createStruct();
return 0;
}
/*
* aStruct.h
*/
#ifndef ASTRUCT_H_
#define ASTRUCT_H_
struct aStruct {
int value1;
int value2;
struct smallerStruct ssTest;
};
typedef struct aStruct aStruct;
aStruct createStruct();
#endif /* ASTRUCT_H_ */
/*
* smallerStruct.h
*/
#ifndef SMALLERSTRUCT_H_
#define SMALLERSTRUCT_H_
struct smallerStruct {
int value3;
};
typedef struct smallerStruct smallerStruct;
smallerStruct createSmallerStruct();
#endif /* SMALLERSTRUCT_H_ */
/*
* aStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
#include "aStruct.h"
aStruct createStruct() {
aStruct asOutput;
printf("This makes sure that this code depends on stdio.h, just to make sure I know where the inclusion directive should go (main.c or aStruct.c).\n");
asOutput.value1 = 5;
asOutput.value2 = 5;
asOutput.ssTest = createSmallerStruct();
return asOutput;
}
/*
* smallerStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
smallerStruct createSmallerStruct() {
smallerStruct ssOutput;
ssOutput.value3 = 41;
return ssOutput;
}
This generates the following error messages:
At aStruct.h:10
field 'ssTest' has incomplete type
At main.c:8
unused variable `asTest' (this one makes sense)
The base of inclusion is to make sure that your headers are included only once. This is usually performed with a sequence like this one:
/* header.h */
#ifndef header_h_
#define header_h_
/* Your code here ... */
#endif /* header_h_ */
The second point is to take care of possible name conflicts by handling manually pseudo namespaces with prefixes.
Then put in your headers only function declarations of public API. This may imply to add typedefs and enums. Avoid as much as possible to include constant and variable declarations: prefer accessor functions.
Another rule is to never include .c files, only .h. This is the very point of modularity: a given module dependant of another module needs only to know its interface, not its implementation.
A for your specific problem, aStruct.h uses struct smallerStruct but knows nothing about it, in particular its size for being able to allocate an aStruct variable. aStruct.h needs to include smallerStruct.h. Including smallerStruct.h before aStruct.h in main.c doesn't solve the issue when compiling aStruct.c.
The multiple definition problem is most likely coming from the way you're including the code. You are using #include "aStruct.c" as opposed to #include "aStruct.h". I suspect you are also compiling the .c files into your project in addition to the #include. This causes the compiler to become confused due to the multiple definitions of the same function.
If you change the #include to #include "aStruct.h" and make sure the three source files are compiled and linked together, the error should go away.
Such errors mean that function declaration (return type or parameter count/types) differs from other function declarations or function definition.
previous declaration message points you to the conflicting declaration.