I have three files as such:
module.c:
void bar() {
foo();
}
module.h: (i didn't put the include guard for simplicity)
void bar();
main.c
void foo() {
//some code
}
int main() {
bar();
}
when compiling main.c and module.c, module.c returns an error saying foo() is not defined. How can i fix this up?
Basically, i wanted to take my actual main file, which was pretty large, and split up parts of it to other files for readability, but those functions call other functions found in main
It's tricky because of the directions your dependencies are going.
I can split your code into three compilation units: main.c, module.c, and foo.c
If you do this, you don't have any foo code in main, main only calls bar, and bar includes foo, which is defined in foo.
main.c
#include "module.h"
int main() {
bar();
}
module.c
#include "foo.h"
void bar() {
foo();
}
foo.c
void foo() {
}
Best of all is that you don't need to declare foo outside of foo.h, or bar outside of module.h.
I guess module.h could also define void foo(); thus module.c would implement foo too. On the other hand, if bar depends indirectly on foo, then maybe module.c should include another_module.h implemented by another_module.c.
Put prototype definitions for all your functions into module.h:
int main(int argc,char **argv);
void foo(void);
void bar(void);
int fludger(int abc,char *str);
You get the side benefit that in addition to putting any function in any .c file you wish, you no longer need to order the functions within a given .c file, based upon what calls what [e.g. before if foo called bar, bar would have to be defined above foo]
Related
I need to generate a static library MyLib.lib that contains unimplemented functions.
Inside the project, I called the unimplemented function as shown below:
/* Inside MyLib.c */
#include "MyLib.h"
void foo(void)
{
func(); // To be implemented by the user.
}
And In the header file MyLib.h, I included a header file
#include "user.h" // contains user_imlplementation_of_func()
...
#define func() user_imlplementation_of_func()
To make things simple, let's just give an example of the user.c:
void user_imlplementation_of_func(void)
{
printf("OK");
}
I would like to know is it possible to do this call? Otherwise, Is there any other solution to use unimplemented functions inside a static library and let the user define them after compressing the project from a source code to a .lib file
You need to declare the unimplemented function as extern in the header of your library. This tells the compiler, that the function will be defined somewhere else.
Example:
MyLib.h
void foo();
extern void func();
MyLib.c
#include "MyLib.h"
void foo(void)
{
func();
}
main.c
#include <stdio.h>
#include "MyLib.h"
void func()
{
printf("Hello, world!\n");
}
int main()
{
foo();
}
Example build:
cc -o MyLib.o -c MyLib.c
cc -o out main.c MyLib.o
Output:
$ ./out
Hello, world!
However, for more readability I suggest you to pass your project functions as pointers to your library functions. This is commonly known as callback.
Example:
/* MyLib.c */
#include "MyLib.h"
void foo(void (*func)(void))
{
func();
}
Now you can call the foo function in your project with:
foo(&user_imlplementation_of_func);
Edit:
As stated in the comments by the user theSealion a third solution is the usage of weak symbols. The wikipedia articel "Weak symbol" provides a good explanation with examples.
You can do some else - function pointer:
//youLib.c
extern void (*func)(void) = NULL;
extern void foo()
{
if (func != NULL) {
func();
}
}
//main.c
static void user_imlplementation_of_func(void)
{
printf("Hello\n");
}
func = &user_imlplementation_of_func;
foo(); //Will printf "Hello"
I'm a beginner into Linking, lets say I have two .c files
file1.c is
#include <stdio.h>
#include "file2.c"
int main(int argc, char *argv[])
{
int a = function2();
printf("%d",a);
return 0;
}
and file2.c is
int function2()
{
return 2018;
}
when I compiled, there is a linker error which is multiple definition of function2, but I only define function once in file2.c?
You should create a header file, "file2.h", with:
int function2(void);
and a file "file2.c" with the function: "file2.h" with:
#include "file2.h"
int function2(void)
{
return 2018;
...
}
Then in your main you have to include the header with:
#include "file2.h"
Keep care that all those files should be in the same folder to avoid any link problem
Try something like this:
#include <stdio.h>
#include "file2.h"
int main(int argc, char *argv[])
{
int a = function2();
printf("%d",a);
return 0;
}
file2.h:
extern int function2(void);
and file2.c is
#include "file2.h"
int function2(void)
{
return 2018;
}
And then link it together.
The statement #include "file2.c" effectively incorporates the contents of file2.c into file1.c. Then file1.c is compiled as if it contains:
int function2()
{
return 2018;
}
Those lines define function2; they tell the compiler “Here is function2, create code for it.” Because those lines effectively appear in both file1.c and file2.c, your program has two copies of function2.
Instead, you should create file2.h that contains:
int function2();
That line tells the compiler “There exists a function called function2, but its definition is somewhere else.”
Then, in file1.c, use #include "file2.h" instead of #include "file2.c". This will tell the compiler, while file1.c is being compiled, what it needs to know to compile a call to function2. The compiler will have the declaration it needs, but it will not have the definition, which is not needed in file1.c.
Also, in file2.c, insert #include "file2.h". Then file2.c will contain both a declaration of function2 (from file2.h) and a definition of function2 (from the actual lines in file2.c). The purpose of this is so the compiler can see both the declaration and the definition while it is compiling file2.c, so it can warn you if there is a typographical error that makes them incompatible.
Additionally, in C, you should use int function2(void) rather than int function2(). For historic reasons, the latter leaves the parameters unspecified. Using (void) tells the compiler there are no parameters.
For example, let's say I have 2 header files.
a.h
#include <stdio.h>
static __inline foo()
{
// do something
}
Then a.h file gets included into b.h:
b.h
#include "a.h"
void bar();
With corresponding b.cpp file:
b.c
#include "b.h"
void bar()
{
foo();
}
main.c
#include "b.h"
void main()
{
bar();
}
Is foo() going to be inlined in b.c file?
Is foo() (static) going to be visible in main.c file since it's included via b.h file or it will be just visible to b.c? (Would guess that it won't be visible since they are not in same translation unit).
foo() is visible in both b and main. The compiler sees the files after the preprocessor has done its job.
main.c after the preprocessor step:
<all the stuff from stdio.h>
static __inline foo()
{
// do something
}
void bar();
void main()
{
bar();
}
One way to remove foo() from main.c is to move inclusion of a.h from b.h to b.c:
Modified b.h:
void bar();
Modified b.c:
#include "a.h"
#include "b.h"
void bar()
{
foo();
}
Is foo() going to be inlined in b.c file?
It is better to say "inlined" into function bar(). Probably it is, but not guaranteed. It is a compiler's decision to inline function or not. Marking function as inline is often just a hint, that may be ignored. Refer to your compiler docs to clarify actual behavior.
Is foo() (static) going to be visible in main.c file since it's
included via b.h file or it will be just visible to b.c? (Would guess
that it won't be visible since they are not in same translation unit).
foo() is visible in every translation unit that includes a.h directly or indirectly. Assuming inlining was ommited, there is another interesting point: each translation unit defines its own copy of foo() i.e. machine code for foo() will be generated for each compiled source. It may be wasteful for non-trivial functions since it leads to bloating of generated code. As consequence you should define static functions in headers only if they are small and are intended to be inlined.
I read that
A function with internal linkage is only visible to one compilation
unit. (...) A function declared static has internal linkage
For .c files it sorta makes sense, but I was wondering what happens with static functions in headers, which get included by multiple .c files but usually have an include guard.
I was reading this answer about static functions in headers, and the first item mentions that it doesn't create a symbol with external linkage and the second item mentions the function is available purely through the header file. Isn't that contradictory? How can the function be available and at the same time have no external symbol? So I did a little test:
/* 1.h */
#ifndef ONE_H
#define ONE_H
#include <stdio.h>
static void foo() {
printf("foo from 1.h %p\n", foo);
return;
}
void bar();
#endif
/* 1.c */
#include "1.h"
#include <stdio.h>
void bar() {
printf("foo,bar from 1.c %p,%p\n", foo, bar);
foo();
}
/* 2.c */
#include "1.h"
#include <stdio.h>
int main() {
printf("foo,bar from main %p,%p\n", foo, bar);
foo();
bar();
return 0;
}
...
debian#pc:~ gcc 2.c 1.c
debian#pc:~ ./a.out
foo,bar from main 0x400506,0x400574
foo from 1.h 0x400506
foo,bar from 1.c 0x400559,0x400574
foo from 1.h 0x400559
As expected bar is the same across all files, but shouldn't foo be too? Isn't 1.h included only once? Adding inline to foo resulted in the same behavior. I'm kinda lost.
Read here, how a header file basically works. That should clarify about your actual question.
Briefly: A header file is just inserted instead of the corresponding #include directive. So any declarations or definitions are treated by the compiler as if you actually copy/pasted the text into your file.
Anyway, you should be careful with function definitions in a header. This is deemed bad style in general. It blows the code for instance, creating redundant copies of that function. Also Function pointers cannot be compared (you never know ...). It is often better to bundle the functions into a library with just the declarations in a header (non-static then: external linkage). There are good justifications sometimes, however (no rule without exceptions). One of them are inline functions.
-static functions are functions that are only visible to other functions in the same file (more precisely the same translation unit).
Check this article for a detailed explanation on linkage: http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
In a C program, where do you define a function?
Why?
I suppose that the function definition is generally written outside the main function and after the function declaration. It's correct? Why?
Thank you all!
You have to define a function outside main(), because main() is a function itself and nested functions are not supported in C.
Declaring a function is in modern C not necessary, because a function definition implies a function declaration. There are still two reasons to do it:
A function declaration can be exported in a header file and then used by other translation units that import the header file.
C is usually translated one-pass that means that you cannot use a function before it is declared without warning. If you have a function a() calling a function b()and vice versa, you cannot define both functions before declaring at least one.
The only real requirement is that a function be declared before it is first called in a statement, and that it be defined somewhere before everything is linked together (either in another source file that gets translated, or in a previously translated object file or library).
If your program is small and you have everything in a single source file, my recommended practice is to define the function before it is used, like so:
void foo( void )
{
// body of foo
}
void bar( void )
{
...
foo();
...
}
int main( void )
{
...
bar();
...
}
The function definition also serves as a declaration (specifying the return type as well as the number and types of parameters to the function). You could put the definitions after main, but you will still need to declare them before they're called:
int main( void )
{
void bar( void );
...
bar();
...
}
void bar( void )
{
void foo( void );
...
foo();
...
}
void foo ( void )
{
// body of foo
}
You don't have to declare foo within the body of bar, or bar within the body of main; you could declare them both before `main:
void foo( void );
void bar( void );
int main( void )
{
...
bar();
...
}
void bar( void )
{
...
foo();
...
}
The only problem with this style is that if you change the return type of the function or change any of the parameters, you have to chase down any declarations and change them as well. The first way (defining before use) reads "backwards", but it's less of a maintenance headache.
If your program is divided up among multiple source files, the usual practice is to create a separate header file for each source file, and #include that header in any other source file that uses those functions, like so:
/**
* foo.h - Header file for function foo
*/
#ifndef FOO_H // Include guards; prevents the file from being processed
#define FOO_H // more than once within the same translation unit
void foo( void ); // declaration of foo
#endif
/**
* foo.c - Source file for function foo
*/
#include "foo.h"
...
void foo( void ) // definition of foo
{
// body of foo
}
/**
* bar.h - Header file for bar.h
*/
#ifndef BAR_H
#define BAR_H
void bar( void ); // declaration of bar
#endif
/**
* bar.c - Source file for bar.h
*/
#include "foo.h" // necessary because bar calls foo
void bar( void )
{
...
foo();
}
/**
* main.c - Source file for main
*/
#include "bar.h" // necessary because main includes bar
int main( void )
{
...
bar();
}
Note that the header files only contain the declarations of foo and bar, not their actual code. In order for this to work, both foo.c and bar.c must be compiled along with main.c, and the resulting object files must all be linked together. You could do them all at once, like:
gcc -o blah main.c foo.c bar.c
Or you could compile each separately and link the object files together:
gcc -c foo.c
gcc -c bar.c
gcc -c main.c
gcc -o blan main.o foo.o bar.o
Or you could build a library out of foo.c and bar.c and link against that (useful if you want to use foo and bar in other programs):
gcc -c foo.c
gcc -c bar.c
ar cr libblurga.a foo.o bar.o
gcc -o blah main.c -lblurga
Standard C does not support nested functions (that is, defining a function within the body of another function). Some implementations such as gcc support nested functions as an extension, but it's not the usual practice.
Good question. Languages in the Pascal family usually do have the concept of scoped functions, like any other declaration/definition.
I think the answer lies in the origins of C as, heaven forgive me, a better macro assembler of sorts (with a standard library). Functions are mere jump addresses with a little stack magic for parameter and return value handling; function "scope" is just too abstract a concept in that world.
That said, a similar effect can be achieved by grouping "helper functions" together with a globally visible function which needs them in the same file; the helper functions would be declared static and could then only be used in that source file. The net effect is quite similar to scoped functions.
Private declaration goes on top of your .c file:
static int your_function();
Private declaration can be emitted if it is defined above where you are attempting to call it, although for maintainability it's always better to declare your private interface, just like your public, in one place.
Public declaration in your .h file:
extern int your_function();
Keyword 'extern' in header files is always implicitly added to your function declaration, although I tend to attach it explicitly for clarity.
Function definition works for both private and public declarations:
int your_function() {
return 5;
}
Or for private only:
static int your_function() {
return 5;
}
If you mark extern function definition as static, GCC will fail with the following:
error: static declaration of ‘your_function’ follows non-static declaration
When compiler builds your code, it pretty much replaces all your #include statements with the content of the file you are including and the parsing goes from top to bottom as one large file. Once you understand that, most of these things simply start to make sense.