Implicit declaration of function in spite of including header file - c

I have a function myfunc defined in a source file myfunc.c and declared in a header file myfunc.h. Both these files are part of a library.
In another project's (projA) source file, I am including the header file as:
#include "myfunc.h"
and using the function correctly (number of parameters, order, etc).
I've edited the Makefile so it has the path to myfunc.h in it's list of includes (-I).
However, I am still getting a warning about implicit declaration. Since projA has warning = error set, it fails on compilation.
Note: this is not an eclipse issue as here, or a missing header as here, or an undeclared function.
Addendum
int myfunc(char * source, size_t source_len, char * dest, size_t dest_len)
{
// manipulation
strncpy(dest, source, dest_len);
// other stuff
}

Take a look at this https://gcc.gnu.org/onlinedocs/cpp/Ifdef.html
You may need to add this in to your Header files to avoid duplicate inclusion

Related

Defining function in .h vs .c file

I have the following program setup:
// main.c
#include "str.h"
...
trim("Hello");
// str.h
char* trim(char* str) {
return str;
}
// str.c
#include "str.h"
[empty]
And compiled as: $ gcc main.c str.c -o run && ./run, and I get the following error:
/tmp/ccEUb8mH.o: In function `trim':
str.c:(.text+0x0): multiple definition of `trim'
/tmp/ccCiyN5A.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
However, as soon as I change str.h/c to the following declration/definition it works:
// str.h
[empty]
// str.c
#include "str.h"
char* trim(char* str) {
return str;
}
What's the reason the second version works but the first one does not?
I suppose it has to do with that the following will work fine:
char * trim(char * str);
char * trim(char * str);
char * trim(char * str);
char * trim(char * str);
char * trim(char * str);
But with definitions it will not:
char * trim(char * str){return str};
char * trim(char * str){return str};
error: redefinition of ‘trim’
When you define a function in a header file, every source file that includes it will have a definition of that function. And for each source file you compile, it creates an object file containing the function definition. Then when you link those source files together to make an executable, you have multiple definitions of the function which gives you the error.
In your example you compiled and linked in one step, however the object files for each source file are still created as temporary files before being linked.
By putting the definition of trim in str.c, you only have a single definition for it in one file, while the header has a declaration that other modules can use to know how to call the function.
Apart from that it is common practice to put definitions in header files and implementations in source files, there is another way to circumvent the problem:
#ifndef HEADER_H
#define HEADER_H
// header.h contents go here ...
#endif
When the header is included the first time ,HEADER_H is not defined yet, so it will get defined, and the functions / variables will be defined. When the header is included the second time, HEADER_H is already defined, and the whole part of code that is in the ifdef - endif part will be skipped. Though you should put your definitions in the header file, and the implementations into the source file, you should put such a guard into your header files all the same. Note that HEADER_H must be replaced with a different name in each header, normally you just take the name of the header file and replace all minuses - and dots . with an underscore _ .
The reason is linker(ld) sees two definitions of trim function, one from main.c and other from str.c, because the header file is included in both files.
// main.c
#include "str.h"
...
trim("Hello");
the above is equal to
// main.c
char* trim(char* str) {
return str;
}
...
trim("Hello");
and in //str.c you are including str.h , so the str.c contents will be, after inclusion of header contents.
//str.c
char* trim(char* str) {
return str;
}
Now when you issue command: gcc main.c str.c -o run && ./run
str.c:(.text+0x0): multiple definition of `trim'
/tmp/ccCiyN5A.o:main.c:(.text+0x0): first defined here
In the error compiler (precisely the linker) clearly pointed out two definitions of trim.
So, defining functions in header files is not a good practice, there are few scenarios people do that but we need to take care when using, else we will be facing these multiple definitions errors.
Whenever you use #include with any file it's inserted at the spot where your include is. So
// foo.h
void a(char b) {
// code
}
// main.c
#include "foo.h"
// main code
Is equivelent to
// main.c
void a(char b) {
// code
}
// main code
However, nothing stops you from including foo.h multiple times. This causes redefinition errors, which you get in your case. Putting function definitions in your .c file insures it's only included the one time. You can redaclare templates though, so it's common to put something like void a(char b); in your .h file.

static function declarations in header files

I have a static function in a source file that is used by other functions in that same source file. Is it fine to put the declaration for that static function in the header file, even though that header file will be included into other source files? Example:
/* foo.c */
#include "foo.h"
/* exported function; calls g */
void f(void) {
g();
}
static
void g(void) {
/* do something... */
}
/* foo.h */
void f(void);
void g(void);
/* main.c */
#include "foo.h"
int main(void) {
f();
}
Is it fine to put the declaration for that static function in the header file, even though that header file will be included into other source files?
No. Consider the conflict the other source files would have if they had a function/object/macro of the same name.
Even without conflict, an "unused function" warning may occur. #Adrian Mole
By putting static void g(void) in the .h file, it adds an unnecessary potential name conflict.
Simply declare/define that static function at the top of the .c in which it is used.
Is it fine to put the declaration for that static function in the
header file, even though that header file will be included into other
source files?
No. becuse it does not make any sense. and why?
In C, functions are global by default. Unlike global functions in C, access to static functions is restricted to the file where they are declared! Therefore, when we want to restrict access to functions, we make them static.
Another reason for making functions static can be reuse of the same function name in other files. so declaring them static in the header file can cause to name collisons in other source files.
In header files we declare our API functions those we want to expose only. in c files we declare usually auxilary functions as static functions for restricting the scope of those aux functions to the c file only

C - Include only specific function

Alongside main.c file, I have following my_custom_data_structure.c file in my project. My my_custom_data_structure.c file contains a lot of variables, functions, etc.
I am using #include "my_custom_data_structure.c" directive in main.c.
Problem
I would like to import only single function called foo from my_custom_data_structure.c. I don't need all the variables and functions, which are declared in my_custom_data_structure.c file.
Any insights appreciated.
File structure
-
|- main.c
|- my_custom_data_structure.c
Content of my_custom_data_structure.c
#include <stdio.h>
int DELAY = 20;
int SPEED = 7;
char GRANULARITY_CHAR = 'g';
unsigned int RANGE = 3;
void foo(){
// TODO: In future, this function will print SPEED.
printf("foo works!");
}
/*
The rest of this file is filled by a lot
of code, which is not needed for main.c
*/
Content of main.c
#include <stdio.h>
#include "my_custom_data_structure.c"
int DELAY = 3;
int main(){
foo();
printf("Delay is %d", DELAY);
return 0;
}
UPDATED: Added working example
The usual way is to compile them separately. So you have your main.c, and your extra.c, and you should create a extra.h (and include it in main.c).
In this extra.h, put in declarations for anything that is to be exported from your extra.c file.
For example any functions that should be available to other files. All other functions should be declared/defined only in your extra.c as static, so that they are not available as symbols to be linked when main.c is compiled.
Normally, you don't include source files (.c) inside other source files (or inside headers). It's possible (and occasionally necessary), but it isn't usual.
Unless you've designed the my_custom_data_structure.c to allow you to specify which functions are to be compiled, you get everything in the file. For example, you could use:
#ifdef USE_FUNCTION1
void function1(void *, …)
{
…
}
#endif /* USE_FUNCTION1 */
around each function, and then arrange to
#define USE_FUNCTION1
before including the source, but that's not usually a good way of working. It's fiddly. You have to know which functions you use, and which other functions those need, and so on, and it is vulnerable to changes making the lists of USE_FUNCTIONn defines inaccurate. Of course, the source code might have blocks of code like:
#ifdef USE_FUNCTION1
#define USE_FUNCTION37
#define USE_FUNCTION92
#define USE_FUNCTION102
#endif /* USE_FUNCTION1 */
so that if you say you use function1(), it automatically compiles the other functions that are required, but maintaining those lists of definitions is fiddly too, even when the definitions are USE_MEANINGFUL_NAME instead of a number.
Create a header (my_customer_data_structure.h) declaring the functions and any types needed, and split the implementation into many files (mcds_part1.c, mcds_part2.c, …).
Compile the separate implementation files into a library (e.g. libmcds.a), and then link your program with the library. If it's a static library, only those functions that are used, directly or indirectly, will be included in the executable.

How can a declared C function have no implementation?

I am baffled by the lack of implementation code for the function glade_project_get_type in the following code snippets.
From the .c file:
project = g_object_new (GLADE_TYPE_PROJECT, NULL);
From the associated header file:
#define GLADE_TYPE_PROJECT (glade_project_get_type ())
This appears to be the declaration of glade_project_get_type():
GType glade_project_get_type (void) G_GNUC_CONST;
/* From glib/gmacros.h:
#define G_GNUC_CONST __attribute__((__const__))
__attribute__((const)) function attribute
Many functions examine only the arguments passed to them and have no effects
except for the return value.
If a function is known to operate only on its arguments then it can be subject
to common sub-expression elimination and loop optimizations.
*/
Nowhere can I find the implementation code for glade_project_get_type() but the software compiles without error, so obviously there is something that I don't understand.
I expected there to be something somewhere like:
GType glade_project_get_type (void)
{
GType aType;
< some code giving a value to aType >
return aType
}
So, what don't I understand about C programming?
The code implementing glade_project_get_type is in the library libgladeui, which is compiled separately and linked with the glade executable.
The source code for libgladeui is shipped along with that of glade. The definition of the function glade_project_get_type is in the file glade-project.c. You won't find the string glade_project_get_type in that file because the actual code for the function is the result of a complicated macro expansion, coming from the following lines of glade_project_get_type:
G_DEFINE_TYPE_WITH_CODE (GladeProject, glade_project, G_TYPE_OBJECT,
G_ADD_PRIVATE (GladeProject)
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
glade_project_model_iface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
glade_project_drag_source_init))
This macro is defined in the header files for glib, specifically gobject/gtype.h. At some point in its expansion, I would guess that token pasting (the ## preprocessor directive) will be used to take one of the tokens passed to the macro (here glade_project) and define a function whose name is that token concatenated with _get_type.
Here is a simple example of what is going on here:
#define MAKE_FUNC(name, val) int my_ ## name ## _function (void) { return val; }
MAKE_FUNC(magic, 42)
int main(void) {
printf("%d\n", my_magic_function());
return 0;
}
Although at first glance, the program doesn't appear to include a definition of my_magic_function, the macro MAKE_FUNC actually expands to create it. The expansion of MAKE_FUNC(magic, 42) is simply
int my_magic_function(void) { return 42; }
The function glade_project_get_type() is compiled into a library, e.g. libglade. The raw source code of this library doesn't contain a definition exactly, because the source code for this function is generated from a template, which can be viewed here.
The headers you are using only describe the functions available. Headers rarely contain actual source code in C, they generally just contain function and type definitions. The compiler uses the information in the header to know what return types and argument types the functions has or what members are in a struct or union. It is the linker's job to actually make sure the functions you are using have definitions. The linker will link your source code with the precompiled libglade library and connect everything up.

Duplicate Symbol in C

I have two source files:
Source FIle 1 (assembler.c):
#include "parser.c"
int main() {
parse_file("test.txt");
return 0;
}
Source File 2 (parser.c):
void parse_file(char *config_file);
void parse_file(char *src_file) {
// Function here
}
For some reason, when compiling it is giving me the following error:
duplicate symbol _parse_file in ./parser.o and ./assembler.o for architecture x86_64
Why is it giving me a duplicate symbol for parse_file? I am just calling the function here... No?
First off, including source files is a bad practice in C programming. Normally, the current translation unit should consist of one source file and a number of included header files.
What happens in your case is that you have two copies of the parse_file function, one in each translation unit. When parser.c is compiled to an object file, it has its own parse_file function, and assembler.c also has its own.
It is the linker that complains (not the compiler) when given two object files as an input, each of which contains its own definition of parse_file.
You should restructure your project like this:
parser.h
void parse_file(char *);
parser.c
void parse_file(char *src_file) {
// Function here
}
assembler.c
/* note that the header file is included here */
#include "parser.h"
int main (void) {
parse_file("test.txt");
return 0;
}
You're including the parser.c file, which means all the code that is in that file will be "copied" to assembler.c file. That means that the entire contents of parser.c will be compiled when the compiler is compiling parser.c, and then it'll be compiled again when the compiler is compiling assembler.c
That's what headers are for.
In the header you can put only the declarations, so you can include it without creating the same symbols again in a different translation unit.
so you can just create a parser.h containing just the declaration of the function:
void parse_file(char *config_file);
then in your assembler.c you include just the header:
#include "parser.h" //include the header, not the implementation
int main() {
parse_file("test.txt");
return 0;
}
You are including the .c file which contains the definition of the function parse_file. Thus it is defined twice, once in each translation unit, which is not allowed.
As other answers state, including the source means the file will be copied to parser.c and will be defined there as well in the original place (assembler.c). To solve this, either create a header file with your prototype:
parser.h
void parse_file(char *config_file);
And include that file:
assembler.c
#include "parser.h"
int main() {
parse_file("test.txt");
return 0;
}
Or remove the include and provide a clue to the function:
int main() {
void parse_file(char *);
parse_file("test.txt");
return 0;
}
Or even simply remove the include at al. Not good practice, as the compiler (without information on a function) will consider its returned value is an integer and may cause other warnings.

Resources