I have several header files in a library: header1.h, header2.h...
I also have a general header file for the library: mylib.h
I want the user to import the main.h file and get access to only some of the functions in the other header files.
For example, in the library:
// header1.h
void a(void);
void b(void);
-
// mylib.h
// I can't use this:
#include "header1.h"
// because it would make b function visible.
// Link to function a ????????
And in my main program:
// main.c
#include "mylib.h"
int main(void) {
a(); // Visible: no problem
b(); // Not visible: error
return 0;
}
Separate function prototypes into different headers, depending on whether they should be "visible"*1 or not (but be "internal").
header1_internal.h
header1.h
header2_internal.h
header2.h
...
Include into the *_internal.h headers the related *.h header.
Include the *_internal.h headers into your lib's related modules.
Do not include any *_internal.h into mylib.h.
*1: Please note that even when not providing a prototype this way the user might very well craft his/her own prototype and then link the function from mylib. So the functions not prototyped aren't unaccessible.
If void b(void) is not needed by other header file, and you have access to the source file, what about moving the declaration into the source file?
// header1.h
void a(void);
//void b(void);
// header1.c
/* some #include here */
void b(void);
/* other code here */
void b(void) {
/* implement it */
}
Header files only contains functions that should be accessible by user of header. They represent public interface.
Watch this first:
Organizing code into multiple files 1
YouTube link: Organizing code into multiple files 1
Organizing code into multiple files 2
youTube link: Organizing code into multiple files 2
Additionally you can refer Introduction To GCC by Brian Gough to get more insights into compilation and linking process using gcc.
Related
I am writing a C99 library that is distributed among several files, e.g.
// core.h
void my_private_fn();
void API_my_public_fn();
// core.c
#include "core.h"
void my_private_fn() {
do_something();
}
void API_my_public_fn() {
do_something_else();
}
// module_a.h
#include "core.h"
void API_useful_thing();
// module_a.c
#include "module_a.h"
void API_useful_thing() {
my_private_fn();
}
I want only the API_ prefixed functions to be visible by a program using the library, but I also need to expose my_private_fn in core.h in order to be used by module_a.c. Is there a way in C to make my_private_fn only visible within the library?
If the function had to only be visible in the compilation unit where it is defined, then you could declare it static. Because C language offers few possible scopes: a symbol can have only 3 scopes:
local to a block (the block can be a function or a block inside a function)
static scope (static declaration outside of a function): the symbol is only visible in the compilation unit where it is declared
global scope (non-static declaration outside of a function): the symbol is visible throughout the whole program.
At most, you can hide the declaration in a private include file that you do not declare in the official documented API. That way obedient users should not use it. But you cannot prevent users to put the declaration in their own code and use the function.
Put them in an internal header file that's only used inside the library and not distributed to end users—say, core_internal.h.
I found a neater way to lay out my code building upon Serge's answer that I selected, whose most merit goes to.
The key is to put the "private" functions in headers that are only included in C files, not in header files. This way the "private" symbols are available internally but not to an external caller. In a complete example:
core.h:
void my_public_fn();
core_priv.h:
void my_private_fn();
core.c:
#include <stdio.h>
#include "core.h"
#include "core_priv.h"
void my_private_fn() {
printf("Private function called.\n");
}
void my_public_fn() {
printf("Public function called.\n");
}
module_a.h:
#include "core.h"
void module_a_fn();
module_a.c:
#include "core_priv.h"
#include "module_a.h"
void module_a_fn() {
my_private_fn();
my_public_fn();
}
And if we want, we can group possibly multiple modules in a common library header.
library.h:
#include "module_a.h"
// etc.
This way, a program using the library only needs to include one file with only:
main.c:
#include "library.h"
int main() {
//my_private_fn(); // This triggers a compile warning.
my_public_fn(); // I can still reach the "core" public function.
module_a_fn(); // This calls the "private" function internally.
return 0;
}
Compiling with gcc -Wall *.c -o main.o and executing ./main.o yields:
Public function called.
Private function called.
Public function called.
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
What are advantages and disadvantages of both approaches?
Source vs. header implementation
Function definition inside source file
Header file sourcefunction.h contains declaration only.
#ifndef SOURCEFUNCTION_H
#define SOURCEFUNCTION_H
void sourcefunction(void);
#endif // SOURCEFUNCTION_H
Source file sourcefunction.c contains definition
#include "sourcefunction.h"
#include <stdio.h>
void sourcefunction(void) { printf(" My body is in a source file\n"); }
Function definition inside header file
Header file headerfunction.h contains definition which is the declaration at the same time.
#ifndef HEADERFUNCTION_H
#define HEADERFUNCTION_H
#include <stdio.h>
void headerfunction(void) { printf(" My body is in a header file\n"); }
#endif // HEADERFUNCTION_H
No source file is needed.
Consumer
File main.c
#include "sourcefunction.h"
#include "headerfunction.h"
int main(void) {
sourcefunction();
headerfunction();
return 0;
}
Why compile many source files?
We have to compile all source files and remember about them during linking.
gcc -c sourcefunction.c
gcc -c main.c
gcc main.o sourcefunction.o
Make can handle file managing but why even bother?
Is separation of interface and implementation always an issue?
It is obvious reason for big projects and teamwork. The designer specifies the interface. The programmers implement functionality.
What about smaller projects and non-formal approach?
Is removing definition from header files always preventing from linker errors?
Let's assume my program is using another module that defines the function with the same name sourcefunction().
#include "sourcefunction.h"
#include "sourcefunction1.h"
#include "headerfunction.h"
int main(void) {
headerfunction();
sourcefunction();
return 0;
}
Different function interface
File sourcefunction1.h
#ifndef SOURCEFUNCTION1_H
#define SOURCEFUNCTION1_H
int sourcefunction(void);
#endif // SOURCEFUNCTION1_H
File sourcefunction1.c
#include "sourcefunction1.h"
#include <stdio.h>
int sourcefunction(void) { int a = 5; return a; }
By compiling main.c, I get a nice compiler error
sourcefunction1.h:4:5: error: conflicting types for 'sourcefunction'
showing me the location of error.
Same function interface
File sourcefunction1.h
#ifndef SOURCEFUNCTION1_H
#define SOURCEFUNCTION1_H
void sourcefunction(void);
#endif // SOURCEFUNCTION1_H
File sourcefunction1.c
#include "sourcefunction1.h"
#include <stdio.h>
void sourcefunction(void) { int a = 5; printf("%d",a); }
Compiler does not mind multiple declarations. I get ugly linker error.
Can header implementation serve as library?
jschultz410 says
If you are writing a library and all your function definitions are in headers, then other people who do segment their development into multiple translation units will get multiple definitions of your functions if they are needed in multiple translation units
Lets' have
File consumer1.c
#include "headerfunction.h"
void consume1(void) { headerfunction(); }
File consumer2.c
#include "headerfunction.h"
void consume2(void) { headerfunction(); headerfunction();}
File twoConsumers.c
extern void consume1(void);
extern void consume2(void);
int main(void) {
consume1();
consume2();
return 0;
}
Let's compile sources.
gcc -c consumer1.c
gcc -c consumer2.c
gcc -c twoConsumers.c
So far, so good. Now, linking.
gcc consumer1.o consumer2.o twoConsumers.o
Linker error: multiple definition of 'headerfunction', of course.
But I can make my library function static.
File headerfunction.h, afterwards.
#ifndef HEADERFUNCTION_H
#define HEADERFUNCTION_H
#include <stdio.h>
static void headerfunction(void) { printf(" My body is in a header file\n"); }
#endif // HEADERFUNCTION_H
It hides the definition from other translation units.
I shouldn't answer this, but I will.
This can create duplicate definitions unless you really only have a single .c file in your project (unwise). Even the header guards won't prevent files the headers from being included multiple times if those multiple times are with different .c files. When the .obj files are linked together, there will be conflicts.
If only the function declaration and not definition is in the header, then only changes to the interface (the function name, parameters or return type) require recompiling dependencies. However, if the entire definition is in the header, then any change to the function requires recompiling all .c and .h files that depend on it, which, in a larger project, can create a lot of unnecessary recompiling.
It's not the convention. Libraries will not use this convention, so you'll be stuck dealing with their header file structure. Other developers will not use this convention, so you can create confusion or annoyance there.
I am new to eclipse, developing c program in eclipse
I am creating multiple source files in same project, could some one help me to create .h file for main () function and to call in multiple source file
for instance if I have created main.c file, now how to call this main.c into another .c file
The main() function should not be in a header file. It should be in one and only one .c file.
An example of simple layout can be:
//header.h
#ifndef MY_HEADER <----Notice the Inclusion Guards, read more about them in a good book
#define MY_HEADER
void doSomething();
#endif //MY_HEADER
//header.c
#include "header.h"
void doSomething()
{
}
//Main.c
#include "header.h"
int main(void)
{
doSomething();
return 0;
}
But please pick up a good book to learn these basics, You definitely need one.
I had to write few functions which are very long. So, I decided to put them in different files and link them to main.. so that it works as if I wrote function definitions after main().
How do I do it..
In a .h file you put your prototype
#ifndef MY_HEADER_H
#define MY_HEADER_H
void hello(void);
#endif
In a seperate .c file you implement your function such as hello.c
#include "myheader.h"
void hello()
{
printf("Testing function from other file\n");
}
then in main you do
#include "myheader.h"
int main()
{
hello();
return 0;
}
make sure you compile hello.c into hello.o before linking the files or it will tell you that it can't resolve the reference to hello.
Find create a header file that has a file ending of .h .
Lets say this header file is named blah.h.
The general structure of this header will be
#ifndef BLAH_H_INCLUDED
#define BLAH_H_INCLUDED
//code
#endif // BLAH_H_INCLUDED
Those are header guards, to prevent multiple inclusions.
Inside the code you will still your function declarations.
For example, void function(int blah); would be a valid function declaration.
This file is then included at the top of all of your files that uses or defines the functions declared, #include "blah.h"
Then you can define your functions in the other files, and when you link them together the program will work.