Defining external function (module) in the header file in C - c

When I compile the program, outlined below, I am getting the following error(s) back
[igor#localhost ~/I2C]$ make i2c_VIPER DEFINE=-DVIPER
gcc -g -Wall -D__USE_FIXED_PROTOTYPES__ -DVIPER -ansi -lusb -c -o i2c.o i2c.c
In file included from i2c.c:9:
viperboard.h:120: error: expected ‘)’ before ‘*’ token
i2c.c: In function ‘main’:
i2c.c:32: error: ‘usb_dev’ undeclared (first use in this function)
i2c.c:32: error: (Each undeclared identifier is reported only once
i2c.c:32: error: for each function it appears in.)
i2c.c:33: warning: implicit declaration of function ‘i2c_VIPER’
make: *** [i2c.o] Error 1
I've tried many things, more or less semi-blindly, to make it working. The struct parsed_CLI_I2C_t defined by me, works flawlessly. No compilation errors. But, when I try to use struct usb_device from <usb.h> in equivalent way, the compiler is not happy.
What I am doing wrong ?
Relatively detailed description follows.
Let's start with a code snippet from the standard #include < usb.h > <-- link to the full header file
/* Data types */
struct usb_device;
struct usb_bus;
struct usb_device {
struct usb_device *next, *prev;
char filename[PATH_MAX + 1];
struct usb_bus *bus;
struct usb_device_descriptor descriptor;
struct usb_config_descriptor *config;
void *dev; /* Darwin support */
u_int8_t devnum;
unsigned char num_children;
struct usb_device **children;
};
Here is the first local header file #include "viperboard.h"
struct parsed_CLI_I2C_t;
extern int i2c_VIPER (struct usb_device **usb_dev, struct parsed_CLI_I2C_t **CLI_I2C_options);
extern bool OpenDevice(void);
This is the second local header file #include "I2C.h"
typedef struct
{
char *USB_board;
int query;
int write_type;
} parsed_CLI_I2C_t;
extern int parse_CLI_I2C_options (int argc, char *argv[], parsed_CLI_I2C_t **CLI_I2C_options);
The main program looks like this
/* all other standard include stuff skipped for brevity */
#include <usb.h>
#include "viperboard.h"
#include <stdbool.h>
#include "I2C.h"
int main(int argc, char *argv[])
{
parsed_CLI_I2C_t *CLI_I2C_options;
parse_CLI_I2C_options (argc, argv, &CLI_I2C_options);
struct usb_device *usb_dev;
i2c_VIPER (&usb_dev, &CLI_I2C_options);
}
and, finally, this is the external module
i2c_VIPER.c
/* all other standard include stuff skipped for brevity */
#include <usb.h>
#include "viperboard.h"
#include <stdbool.h>
#include "I2C.h"
int i2c_VIPER (struct usb_device **usb_dev, struct parsed_CLI_I2C_t **CLI_I2C_options )
{
bool connected; /* True if the ViperBoard is connected */
connected = OpenDevice();
return(0);
}
This is
OpenDevice.c
#include <stdbool.h>
#include <usb.h>
bool OpenDevice() /* <---- this is line 11 */
{
usb_set_debug( 0 );
/* Initialize USB library */
usb_init( );
etc etc etc
return true;
}
========================================================
30 minutes later: all suggested changes implemented
Another type of error appeared.
OpenDevice.c:11: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘OpenDevice’
make: *** [OpenDevice.o] Error 1

This line
usb_device *usb_dev; /* this is line 32 */
will not work as you're compiling a C program, not a C++ program. In C structures are not automatically types like they are in C++. You need to use the struct keyword to declare structures:
struct usb_device *usb_dev; /* this is line 32 */
This change you have to do for every place where you use structures, for example like the declaration and definition of the i2c_VIPER function.
Also note that for the bool type to work, you need to include <stdbool.h>.

Related

struct declared in tools.h and defined in tools.c. Can't link them to main.c

file tools.h:
//some macro definitions
struct name;
//other function prototypes
file tools.c:
#include "tools.h"
struct name
{
FILE *src;
int value;
}
//definitions of functions declared in tools.h
file main.c:
#include <stdio.h>
#include "tools.h"
int main()
{
struct name *ptr;
ptr = malloc(sizeof(struct name));
ptr->FILE = fopen(filename, "r");
ptr->value = 12;
...
}
At first, I built tools.o by using:
$ gcc tools.c -c
Without any error or warning, tools.o was built in the current directory.
Now, I tried to build executable by using:
$ gcc main.c tools.o -o exe
and I got errors of same type (all the errors were of same type, caused due to accessing the struct element). Here's the sample of that error I got:
main.c: In function ‘main’:
main.c:17:22: error: invalid use of undefined type ‘struct name’
17 | buffer = malloc(ptr->value+1);
Please explain why this happened and what wrong I did while linking or in my code.
tools.h file
#ifndef TOOLS_H
#define TOOLS_H
#include <stdio.h>
struct name
{
FILE *src;
int value;
};
int foo(struct name*);
struct name *bar(double, FILE*, const char *); //prototypes of functions defined in tools.c
#endif
tools.c
#include "tools.h"
int foo(struct name*)
{
/* ... */
}
struct name *bar(double, FILE*, const char *)
{
/* ... */
}
Looks like you have some confusion with regards to forward declaration of a structure and a structure declaration (which defines a type).
From Forward declaration:
a forward declaration is a declaration of an identifier (denoting an entity such as a type, a variable, a constant, or a function) for which the programmer has not yet given a complete definition.
In tools.h, this
struct name;
is forward declaration of structure struct name. Note that, it declares an incomplete type because the specification [list defining the content] of struct name is unknown at this time.
You have included the tools.h in main.c and when compiling main.c compiler does not find the specification of struct name and hence, throwing error on the statements using it.
In tools.c, you are declaring the struct name (which defines a type):
struct name
{
FILE *src;
int value;
};
when compiling tools.c, compiler knows about the specification of structure struct name and hence, it's compilation is successful.
The other post [by #0___________] gives the appropriate way to solve this problem.

Warning: declaration of '...' will not be visible outside this function [-Wvisibility]

First of all, I've googled the error and read these answers:
I don't understand why compiler is giving me error with this code
C : Warning about visibility of a struct
But none of them helped me, so here we are.
The problem resides somewhere in between these 2 structures, prx_data_s which store generic data and prx_ops_s that defines pointers to functions that will use that data.
I'll simplify the sources for the example:
prx_data.h
#ifndef PRX_EXAMPLE_DATA_H
#define PRX_EXAMPLE_DATA_H
#include "prx_ops.h"
struct prx_data_s {
enum prx_op_t op;
char *keyquery;
};
char *get_query(struct prx_data_s *dt);
#endif
prx_data.c
#include "prx_data.h"
char *get_query(struct prx_data_s *dt)
{
return dt->keyquery;
}
prx_ops.h
#ifndef PRX_EXAMPLE_OPS_H
#define PRX_EXAMPLE_OPS_H
#include "prx_data.h"
enum prx_op_t {
PRX_EXAMPLE_OP = 2
};
struct prx_ops_s {
int (*dec) (struct prx_data_s *);
};
#endif
I'm trying to compile the object from the above example with:
clang -c prx_data.c -o prx_data.o -std=c11 -g -Wall
And this is the output error:
In file included from prx_data.c:1:
In file included from ./prx_data.h:4:
./prx_ops.h:11:24: warning: declaration of 'struct prx_data_s' will not be visible outside of this function [-Wvisibility]
int (*dec) (struct prx_data_s *);
^
All help is welcome, thanks :)
You have a problem with circular dependencies in your header:
prx_data.h:
#include "prx_ops.h" <<< Here we do not yet see the struct definition
prx_ops.h:
#include "prx_data.h" <<<< Nothing will be included due to inclusion guards.
struct prx_ops_s {
int (*dec) (struct prx_data_s *); <<<< Here a new struct type is declared.
};
later back in prx_data.h:
struct prx_data_s {
enum prx_op_t op;
char *keyquery;
};
When reading prx_ops.h, you dont 't have prx_data.h included because the compiler is reading prx_ops.h from the include at the beginning of prx_data.h. You thus have to forward declare it.
Try adding
struct prx_data_s;
at the beginning of prx_ops.h`
Hope that helps ~~

C - Unknown type name

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.

File System in Userspace (FUSE) compilation error

/*This is a simple try to create a File System in UserSpace
The pre_init function just initializes the filesystem */
#include<linux/fuse.h>
#include<stdio.h>
#include<stdlib.h>
#include<fuse_lowlevel.h>
static void* pre_init(struct fuse_conn_info *conn, struct fuse_config *cfg){
printf("[init] called\n");
(void) conn;
return NULL;
}
static struct fuse_operations opr = {
.init = pre_init,
};
int main(int argc, char *argv[]){
return fuse_main(argc, argv, &opr, NULL);
}
I am trying to compile the code using gcc sample.c -o sample `pkg-config fuse --cflags --libs` And I'm getting a whole lot of errors in the code as i have shown
sample.c:7:59: warning: ‘struct fuse_config’ declared inside parameter list will not be visible outside of this definition or declaration
static void* pre_init(struct fuse_conn_info *conn, struct fuse_config *cfg){
^~~~~~~~~~~
sample.c:12:15: error: variable ‘opr’ has initializer but incomplete type
static struct fuse_operations opr = {
^~~~~~~~~~~~~~~
sample.c:13:3: error: ‘struct fuse_operations’ has no member named ‘init’
.init = pre_init,
^~~~
sample.c:13:10: warning: excess elements in struct initializer
.init = pre_init,
^~~~~~~~
sample.c:13:10: note: (near initialization for ‘opr’)
sample.c: In function ‘main’:
sample.c:16:9: warning: implicit declaration of function ‘fuse_main’; did you mean ‘fuse_mount’? [-Wimplicit-function-declaration]
return fuse_main(argc, argv, &opr, NULL);
^~~~~~~~~
fuse_mount
sample.c: At top level:
sample.c:12:31: error: storage size of ‘opr’ isn’t known
static struct fuse_operations opr = {
^~~
I have also checked that fuse is installed properly as the header files have been included without any issues. But why am I not able to compile this simple code?
There are two "fuse" versions, sometimes coexistent with each other: fuse2 and fuse3. And they differ. In my Archlinux there are two fuse packages: fuse2 and fuse3. On my system, file /usr/include/fuse.h just includes fuse/fuse.h and fuse/fuse.h comes from fuse2 packages. Header fuse3/fuse.h comes from fuse3.
Anyway, you want to use fuse3 api here as you use struct fuse_config. fuse3 defines struct fuse_config.
But, thirst of all, define FUSE_USE_VERSION macro before including any of the fuse header files, as specified in the beginning in fuse.h from fuse2 and in the fuse.h from fuse3:
IMPORTANT: you should define FUSE_USE_VERSION before including this header.
The following compiles with no warnings/errors using gcc -Wall -pedantic -lfuse3 1.c on my platform:
#define FUSE_USE_VERSION 31
#include <fuse3/fuse.h>
#include <stdio.h>
#include <stdlib.h>
static void* pre_init(struct fuse_conn_info *conn, struct fuse_config *cfg){
printf("[init] called\n");
(void) conn;
return NULL;
}
static struct fuse_operations opr = {
.init = pre_init,
};
int main(int argc, char *argv[]){
return fuse_main(argc, argv, &opr, NULL);
}

Makefile for sql parser... writing dependencies

I'm implementing a sql parser in lex and yacc,
in that I use a symbol table which I kept in a separate .h file (sql.h) and in this header file I have some functions declarations.
The definitions of these functions are kept in a .c file (sql.c). Now I have included sql.h in sql.c,
I refer to the symbols and functions from sql.h in both my lex file(1.l) and yacc file(1.y).
The problem is that I'm not able to write a proper makefile for this.
I'm getting errors like multiple declarations.
Where do I include which file and how to write dependencies?
Please help. I have searched for a solution but I'm not getting it.....
Update:
I compile the code like this:
lex 1.l
yacc -d 1.y
gcc lex.yy.c y.tab.c sql.c -ll -ly
I get the following errors after the third command of gcc:
In file included from 1.l:5:
sql.h:17: warning: ‘SQL’ initialized and declared ‘extern’
sql.h:18: warning: ‘SQL_SEL’ initialized and declared ‘extern’
1.l: In function ‘makeTable’:
1.l:80: warning: assignment from incompatible pointer type
In file included from 1.y:7:
sql.h:17: warning: ‘SQL’ initialized and declared ‘extern’
sql.h:18: warning: ‘SQL_SEL’ initialized and declared ‘extern’
sql.c:3: error: redefinition of ‘SQL’
sql.h:15: note: previous definition of ‘SQL’ was here
sql.c:4: error: redefinition of ‘SQL_SEL’
sql.h:16: note: previous definition of ‘SQL_SEL’ was here
sql.h:
#ifndef SQL_H
#define SQL_H
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct sym_table {
char *token;
char *value;
struct sym_table *next;
};
struct sym_select {
char **cols;
};
extern struct sym_table *SQL = NULL;
extern struct sym_select *SQL_SEL = NULL;
void addSymbol(char *, char *);
void print(struct sym_table *);
void showTable(struct sym_table *);
void makeTable(struct sym_table *, int);
sql.c:
#include "sql.h"
struct sym_table *SQL = NULL;
struct sym_select *SQL_SEL = NULL;
And the definitions of the functions declared in sql.h
1.l file:
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
#include "sql.h"
int lineno=1;
void makeTable(struct sym_table *, int);
%}
..... and othr lex file
1.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int lineno;
extern void yyerror(char *);
#include "sql.h"
%}
.... and other yacc file data
Can you suggest me some other way to get around this?
Please post your Makefile. As far as i understand there's also a problem with code, not only with Makefile. Or it could be that you try to make 1.o from 1.l and different 1.o from 1.y.
Normally the dependencies should look something like:
1l.o: 1.l sql.h; # lex invocation
1y.o: 1.y sql.h; # bison invocation
sql.o: sql.c sql.h; # cc invocation
prog: 1l.o 1y.o sql.o; # ld invocation
Probably you will also need to depend on tokens' declaration file.
EDIT:
Ah, so probably you need to put the definition of that table into one file, and the declaration into the header. You must first understand the difference between declaration and definition in C. For example if you have the following files:
aaa.h
int arr[]={1};
aaa.c
#include "aaa.h"
bbb.c
#include "aaa.h"
And then you try to cc -o aaa aaa.c bbb.c, you get the multiple definition error. That means, that the actual array must be in one file, and in the header it should be something like extern int arr[];
Update:
You should remove setting to NULL in sql.h. It's only a declaration there, that there is such and such variable somewhere. The actual value is to be assigned in sql.c.
extern struct sym_table *SQL = NULL;
extern struct sym_select *SQL_SEL = NULL;
Remove the initialization = NULL from the header file.

Resources