Definition of a function in a C program [closed] - c

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.

Related

Splitting main file into modules in C

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]

Violating static function in C

In one interview I was asked, if in one file A, some static function is defined and in file B you want to use this static function -- how you will use it?
My answers were:
declaring in .h file
But if we declare that in a header file, other files which will include this also have access to this static function.
wrapper concept: Declaring a new function newfun in file A, which will call static function and calling this newfun in file B.
But he was not satisfied with these answers.
Can you please provide me some better solution to violate static.
Perhaps they wanted to hear about function pointers?
You can create a pointer to the function, and call it using that pointer.
One possible scenario where this is reasonable is if you have a callback function that you don't want to be callable by everyone, and you give the pointer as an argument to some register_callback function.
Callback functions were used extensively, for example to let the user of a GUI API provide code for what should happen when a button is pressed. Nowadays, with object-oriented languages, it is more common to subclass a class and define or override methods, such as the Android View class and the method OnClickListener, but C# delegates are very similar to C function pointers.
To illustrate the principle, here is the source code (the file "B" in the original question) for some sort of library, where the main component is the do_stuff function:
#include <stdio.h>
#include "some_library.h"
void (*stored_callback)(void) = NULL;
void register_callback(void (*callback)(void)) {
stored_callback = callback;
}
void do_stuff(void) {
printf("Doing stuff...\n");
printf("Calling callback...\n");
if (stored_callback != NULL)
stored_callback();
}
This header, some_library.h, file shows the API of that library:
extern void register_callback(void (*callback)(void));
extern void do_stuff(void);
And here is how the library is used (the file "A" in the question):
#include <stdio.h>
#include "some_library.h"
static void my_callback(void) {
printf("Inside the callback!\n");
}
int main(void) {
register_callback(my_callback);
do_stuff();
return 0;
}
My interview answer would be "You can't."
(Because the question says "in file B you want to use this static function" and it didn't say you are allowed to modify file A.)
I'm assuming you don't have access to the source of the static function or else you could just remove the static keyword or expose the function via an exported wrapper or global function pointer.
You can still use the static function if you use objcopy to manually change the visibility on the symbol in the object file / library.
Suppose this is the (unaccessible) static function:
//static.c
#include <stdio.h>
static void fun(){
puts("Hello world");
}
Suppose you only have static.o, obtainable with gcc -c static.c.
Now, let's assume you want to link static.o with main.o made from
//main.c
void fun();
void main(){
fun();
};
To be able to link it, you need to turn
$ nm static.o
0000000000000000 t fun
U puts
into
0000000000000000 T fun
U puts
You can do that with:
objcopy --globalize-symbol=fun static.o global.o
Now you can link with global.o instead of static.o.
$ gcc main.o global.o && ./a.out
Hello world
filea.c
#include <stdio.h>
#include "filea.h"
static void hidden(void) { printf("inside hidden function.\n"); }
fxptr unhide(void) { return hidden; }
filea.h
#ifndef FILEA_INCLUDED
#define FILEA_INCLUDED
typedef void(*fxptr)(void);
fxptr unhide(void);
#endif
fileb.c
#include "filea.h"
int main(void) {
unhide()();
return 0;
}

Linkage and static function confusion

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

Default function implementation for linking

I have a family of executables pieced together from a set of .o files. There's some reusable ones, and then usually a couple of executable specific modules. One of the reusable pieces wants to provide a sort of "application hook". But many of the executables just do a standard no-op thing. While a couple of others actually want to define interesting behavior for said hook.
What would be ideal, is if there was a way to provide a standard default version of the function, which the linker would use if none of the other .o files defined said function, but if they did, use the others.
Is there any way/technique to approximate this sort of thing with just straight C?
If you're using GCC as your compiler, then you can declare the replaceable functions like this:
void foo() __attribute__ ((weak));
Here's an example on how this works. In your main.c file:
#include <stdio.h>
void foo()__attribute__ ((weak))
{
printf("%s", "Hidden foo\n");
}
int main()
{
foo();
return 0;
}
In another file, foo.c:
#include <stdio.h>
void foo()
{
printf("%s", "foo\n");
}
Now when you only compile, link and run main.c, you'll get:
gcc main.c -o main
./main
Hidden foo
If you instead also compile foo.c, you'll get:
gcc main.c foo.c -o main
./main
foo
The weak version of foo() was replaced.
On a real setup, you would probably use a header file to provide the function prototypes:
void foo();
and then implement the weak version of those functions like this:
__attribute__ ((weak)) void foo()
{
// ...
}
You could also use a macro to make this a bit more readable:
#define WEAK_SYMBOL __attribute__ ((weak))
So that you'll get:
WEAK_SYMBOL void foo() { /* ... */ }

Are static functions in C language really invisible?

I was told that a function defined as static in one .c file is not accessible from other files. But in the following program, I can access the static void show() function from another file. Is my understanding of static functions in C wrong?
a.h (first file):
static void show()
{
printf("I am in static show function in a.c");
}
b.c (another file):
#include"a.h"
void main()
{
show();
}
Remember that #includes work by copy-and-pasting the content of the included file. So in your example, after the #include has been processed, you get this:
static void show()
{
printf("I am in static show function in a.c");
}
void main()
{
show();
}
So clearly main can see show.1
The solution is to not #include .c files. In general, you should only #include header (.h) files. Your static functions shouldn't be declared or defined in the header file, so main will not be able to see it.
1. However, you now actually have two definitions of the show function, one in a.c and one in b.c. For static functions, this isn't a problem, but for non-static functions you would get a linker error.
static keyword changes the linkage specification to Internal Linkage.
A function marked as static will only be visible in that Translation Unit(TU).
Perhaps, You have same named symbols available in that particular TU, where you access the function. The how part of it can be only answered after you show us the code.
EDIT:
When you define a static function in header file, A copy of the same function gets created in every Translation Unit where you include it.Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals.
Clearly, this will work but this might as well increase the size of your generated binary.
The other answers are correct, but it's not quite accurate to say that the static function is not accessible from another file. It is possible to access the function through a function pointer. It would be more accurate to say that the name of the function is not accessible in another translation unit.
Remember that converting C source code to an executable program consists of conceptual stages, including:
preprocessing (in which #include directives are replaced with the contents of the included file
compilation (which processes one translation unit at a time)
linking (in which the translation units are put together into the final program)
Suppose we have three files. foo.h:
typedef void (*void_function_p)(void);
extern void_function_p foo(void);
foo.c:
#include "foo.h"
#include <stdio.h>
static void baz(void) {
printf("worked!\n");
}
void_function_p foo(void) {
return baz;
}
bar.c:
#include "foo.h"
#include <stdio.h>
int main(void) {
(*foo())();
return 0;
}
This program compiles and prints "worked!" when it runs.
There are two translation units here. One is the code in the preprocessed foo.c (which, because of how #include works also includes the code in foo.h and stdio.h). The other is the code in the preprocessed bar.c (which, again, has its own copy of the code in foo.h and stdio.h).
By having the function foo return a pointer to the static function baz, we are able to call baz from the main function.
Now, consider what happens if we modify main to look like this:
int main(void) {
(*foo())();
baz();
return 0;
}
This code will result in a linker error because the name baz in this translation unit cannot be linked to the definition of baz in the other translation unit.
This is the first advantage of static functions: another programmer cannot accidentally access our baz function from another translation unit.
Now, consider what happens if we modify bar.c to look like this:
#include "foo.h"
#include <stdio.h>
static void baz(void) {
printf("still works!");
}
int main() {
(*foo())();
baz();
return 0;
}
This code will compile, and print "worked!" followed by "still works!"
This is the second advantage of static functions: we've defined two functions (in different translation units) with the same name.
If you try to put both static definitions in the same translation unit, you will get a compiler error about defining baz twice.
As a final note, if you take the program as it now stands and remove all the statics, it will result in a linker error because baz has been defined twice (with external linkage), which is not permitted.

Resources