Strange makefile build error - c

I'm working on this very simple part of code, but somehow the build error is pretty strange to me.
I have these files in the project: main.c, http_request.h, http_request.c; and a simple Makefile.
1. http_request.h
/* STRUCTURES */
struct http_param {
char key[MAX_BUFFER];
char *value;
};
struct http_request {
int size;
struct http_param data[MAX_PARAM];
};
/* FUNCTIONS */
int parse_http_request(apr_pool_t *pool, const char *args, struct http_request *req); /* (A) */
2. http_request.c
#include <http_request.h>
...// something else goes here, it's fine
int
parse_http_request(apr_pool_t *pool, const char *args, struct http_request *req) /* (B) */
{
3. Makefile
-I$(PROJECT_DIR)/include
this directory contains http_request.h.
Then I build, it raises this error:
/project/src/http_request.c:14: warning: 'struct http_request' declared inside parameter list
/project/src/http_request.c:14: warning: its scope is only this definition or declaration, which is probably not what you want
/project/src/http_request.c: In function 'parse_http_request':
The error points to (A) and (B) as I mentioned in source code above.
Could anyone help to find out what the problem is?
Thanks.

I suspect, seeing that you use apr_pool_t, that you also have apache includes in your include path. apache also provides a file called http_request.h and that one gets included instead of the one you have.

use
#include "http_request.h"
instead of
#include <http_request.h>

Related

Passing struct pointer as a parameter

I'm trying to compile this code in c. First of all i have this struct in a separate source file to use it like a "class" (dir.h)
//Structure
typedef struct s_dirobject {
int noteid;
char title[20];
int bytes;
char head[20];
bool is_dir;
struct s_dirobject* next;
} dirobject;
//Ops
void add_dirobject(dirobject* myDirobject,int num_dirobject, char title[20], int is_dir, int bytes, char head[20]);
int get_dirobject_noteid(dirobject* myDirobject,int num_note);
char* get_dirobject_title(dirobject* myDirobject,int num_note);
int get_dirobject_bytes(dirobject* myDirobject,int num_note);
char* get_dirobject_head(dirobject* myDirobject,int num_note);
bool isdir(dirobject* myDirobject, int num_note);
int get_dirobjects_len(dirobject* myDirobject);
void clear_dir(dirobject* myDirobject);
void init_dir(dirobject* myDirobject);
In second place i have the comms source to retrieve the contents of a directory from a remote file system, and fill the object (comms.c)
#include "notebook.h"
#include "dir.h"
dirobject* temporaldirobjects;
...
init_dir(temporaldirobjects);
while(cond) {
//Add retrieved item to the directory
add_dirobject(temporaldirobjects, index, title, is_dir, bytes, "");
}
//When done retrieving the contents from the source i do instantiate the notebook_window
notebook_init(source, path, temporaldirobjects);
Finally, my notebook window interface will look like this. (notebook.h)
#include "dir.h"
void notebook_init(char* source, char* path, dirobject* contents);
void notebook_deinit();
And its implementation (notebook.c)
void notebook_init(char* source, char* path, dirobject* contents) {
// Fill the vars
this_window_source=source;
this_window_path=path;
this_window_dirobjects=contents;
...
}
When i compile this code as is, i get the error saying that
../src/dir.h:13:16: error: redefinition of 'struct s_dirobject'
In file included from ../src/notebook.h:12:0,
from ../src/comms.c:25:
../src/dir.h:13:16: note: originally defined here
In file included from ../src/comms.c:27:0:
../src/dir.h:20:3: error: conflicting types for 'dirobject'
In file included from ../src/notebook.h:12:0,
from ../src/comms.c:25:
../src/dir.h:20:3: note: previous declaration of 'dirobject' was here
In file included from ../src/comms.c:27:0:
../src/dir.h:23:6: error: conflicting types for 'add_dirobject'
In file included from ../src/notebook.h:12:0,
from ../src/comms.c:25:
../src/dir.h:23:6: note: previous declaration of 'add_dirobject' was here
...
since the comms library includes dir.h and notebook.h, and notebook.h does it too.
and if i remove the include in notebook.h i got this other error:
In file included from ../src/comms.c:25:0:
../src/notebook.h:14:46: error: unknown type name 'dirobject'
How can i acheive this? I would like to keep it as clean code as i can.
You included two headers in file comms.c
#include "notebook.h"
#include "dir.h"
header notebook.h in turn includes header dir.h
#include "dir.h"
void notebook_init(char* source, char* path, dirobject* contents);
void notebook_deinit();
As result the structure is defined twice in the same compilation unit. You have to provide that each headers would be included only once in each compilation unit. To do this you have to supply header's quards. For example
#ifndef DIR_H
#define DIR_H
//Structure
typedef struct s_dirobject {
int noteid;
char title[20];
int bytes;
char head[20];
bool is_dir;
struct s_dirobject* next;
} dirobject;
//...
#endif
Or if the compiler supports #pragme once then you could use it.
Usually, multiple declarations are fine in c but multiple definition is not. In your code, you are including dir.h multiple times which is causing the redefinition of struct s_dirobject. Read something about "Header guard" or "Include Guard". here. Hope this solves your major issues with redefinitions.

error: dereferencing pointer to incomplete type -> passing structure to module

The structure:
#include <gtk/gtk.h>
#include "db_interface.h"
struct AddNewEmployee {
const gchar *fname;
const gchar *lname;
};
void new_emp_get_data(GtkWidget *widget, gpointer add_emp_window)
{
struct AddNewEmployee n_e_s; //new employee struct
<gtk portion removed to clean code>
n_e_s.fname=gtk_entry_get_text(GTK_ENTRY(first));
n_e_s.lname=gtk_entry_get_text(GTK_ENTRY(last));
db_add_new_emp(&n_e_s); //pass the struct to db_interface to add new employee
}
The header file (db_interface.h)
#ifndef DB_INTERFACE_H
#define DB_INTERFACE_H
struct AddNewEmployee *n_e_s;
void db_add_new_emp(struct AddNewEmployee *n_e_s);
#endif
The second module (db_interface.c)
#include <stdio.h>
#include "db_interface.h"
void db_add_new_emp(struct AddNewEmployee *n_e_s)
{
printf("Greetings from db_interface, %s\n", n_e_s->fname);
}
When I try to compile the code using GCC, I get the message "error: dereferencing pointer to incomplete type". I have tried several different answers I found when others posted their problems with this error, but have yet to find one that works. I copied the code in the function from the db_interface.c module to the original module - the one containing the struct - and it worked fine, so I know my problem lies with sending the structure to the db_interface.c module.
Just move the struct AddNewEmployee to db_interface.h and it should compile just fine.
Both .c files need to know how the struct is implemented.

Multiple definition error upon including headers( How to add header in c?)

I have such project, which includes 1.c 2.c and mygost.h files.
//mygost.h looks this way
#ifndef MYGOST_H_
#define MYGOST_H_
#include <stdint.h>
uint8_t transl_table(uint8_t in, uint8_t n) {
return tbl[n][in];
}
const char *get_filename_ext(const char *filename)
{
const char *dot = strrchr(filename, '.');
if(!dot || dot == filename) return "";
return dot + 1;
}
#endif
//1.c
#include <malloc.h>
#include "mygost.h"
// here we call defined before functions
//2.c
#include <malloc.h>
#include "mygost.h"
// here we call defined before functions
If I include this header only in one .c file, everything will be fine. Otherwise I get Multiple definition error of const char *get_filename_ext(const char *filename) function and all other function in the header. In addition, I dont redefine these functions in a code at all. Don`t know how to fix this.
I use QNX Momentics Tool Suite, which has own compliler (http://www.qnx.com/products/tools/qnx-momentics.html), but it works like gcc as far as I know.
UPD1: Compiler gives such errors
Severity and Description Path Resource Location
2.c: multiple definition of `get_filename_ext' GostQnx line 0
..........
make[2]:***[C:/ide-4.5-workspace/GostQnx/x86/o-g/GostQnx_g] Error1 GostQnx line 0
make[2]:***[C:/ide-4.5-workspace/GostQnx/x86/o/GostQnx] Error1 GostQnx line 0
first defined here GostQnx mygost.h line 16
................
multiple definition of `get_filename_ext'GostQnx mygost.h line 151
..........
UPD2: adding static or inline don`t effect.
You should not define a function in a .h file. The error is most likely the missing function prototype const char *get_filename_ext(const char *);
(edited following comment)
//mygost.h looks this way
#ifndef MYGOST_H_
#define MYGOST_H_
#include <stdint.h>
extern uint8_t transl_table(uint8_t in, uint8_t n);
extern const char *get_filename_ext(const char *filename);
#endif
//mygost.c looks this way
#include "mygost.h"
extern uint8_t transl_table(uint8_t in, uint8_t n) {
return tbl[n][in];
}
extern const char *get_filename_ext(const char *filename)
{
const char *dot = strrchr(filename, '.');
if(!dot || dot == filename) return "";
return dot + 1;
}
When you include in 1.c, the compiler declares the function and make an assumption on it's prototype since it is not defined. And does the same the second time it is included in 2.c. The usual way would be to declare a function prototype in mygosh.h, and put the actual function declaration in a mygosh.c containing the implementation details.
Bear in mind that I only rewrote according to your example (for example I did not correct the undeclared variable in trans1_table)
Having the full output from the compiler would help to be more precise. As the compiler and platform (ex: gcc 4.7 under ubuntu 12.04).
Also, I tried to compile your code under fedora 19 with gcc 4.7 and it does not compile because of some unknown types that are either defined elsewhere in your real project or because it could also be a cause of your problem. Try to rewrite as a self contained compilable example. If you want, you can check a gitorious project I started out a while ago for another stack overflow question you can look at for ideas.
https://gitorious.org/c-cli-rubix-cube

Clear tutorial explaining modular programming in C?

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.

Passing structs by pointer in C89

I am working with a C89 compiler and I'm coming across some pointer typing error.
Calling code:
struct cpu_state_type cpu_state;
//Stuff here....
foo()
{
print_out_cpu(&cpu_state);
}
Print_out_cpu is defined elsewhere and the H file is #included in.
struct cpu_state_type
{
int r[12];
};
void print_out_cpu(struct cpu_state_type *c);
I get error:
error: incompatible type for argument 1 of 'print_out_cpu'
As best as I can understand,&cpu_state returns type cpu_state_type*, so I am confused.
Are you sure the prototype has the * in it? If I compile (gcc -std=c89) the following code, I get that exact error:
struct cpu_state_type {
int r[12];
};
// note that it is the structure as the param here (not the pointer)
void print_out_cpu(struct cpu_state_type c);
struct cpu_state_type cpu_state;
foo()
{
print_out_cpu(&cpu_state);
}
I don't see any problems, so I wonder if it's an error in your include statement or in the file, etc.
It'll be difficult to determine the cause of the error without seeing more of the source. Try creating a source file like:
#include struct cpu_state_type cpu_state;
void foo() {
print_out_cpu(&cpu_state);
}
If that doesn't trigger the problem, keep adding things until it does.
If it does trigger the problem, extract the pertinent parts of the header file into your source (and remove the #include) and try again.

Resources