Why should I declare a function in C? [duplicate] - c

This question already has answers here:
Must declare function prototype in C? [duplicate]
(10 answers)
Closed 7 years ago.
I have two source files test1.c and test2.c.
In test1.c:
#include <stdio.h>
void main() {
checks(); }
In test2.c:
#include <stdio.h>
void checks(){
printf("This is a sample Text");
}
In this case I can successfully build and run this program.
So why should I use:
void checks();
To declare the function?
It seems perfectly fine now.
I am Using C99.

In your case, the check() function has a very simple prototype and the default prototype applied by the C compiler is to accept anything as argument and to return an int. It is probably what is done here (except that, as you do not store the result of the function it is optimized out without noticing it).
If you want to check my theory, try to write this (and it should work until it reaches the linking phase):
int result = check();
At the end, your code work because the linker finally find something that work to plug for the check() function (yet, it should still expect an int at some point).
In fact, the declaration of a function prototype is only useful in two cases:
The code of the function and the use of the function are in the same file.
When you use the function before its declaration (code source), then you need to tell the compiler what to expect when trying to statically type the function you are writing (the compiler read a source code file from top to bottom).
For example:
int bar (int a, int b, bool c);
int foo (int a, bool b) {
int result = bar (a, a, c);
...
}
int bar (int a, int b, bool c) {
...
}
The code of the function the use of the function are not in the same file.
Then, you usually get the definition of the function through a header file which collect all the information needed by the compiler to know how to statically type your code. The header file (*.h) contains all the prototypes of the functions of the module you are using. The implementation of the functions will come after at linking time.
Note that, I usually try to avoid the first case because it is really not logical. When you read a source code, you go from top to bottom, just as the compiler do, and you expect to find the function definition before its usage... So, it is much more logical to structure your code in a way that do not need to require such artifacts. In my humble opinion...

Related

Declare global variable after function

Why do we need to declare global variables before function defining and declaring since we call this function after this variable declaration? Isn't it that compiler read line by line? I mean while calling the function compiler should know what's x.
void function()
{
x += 3
}
int x = 3;
int main(void)
{
function();
return 0;
}
And one more question. I know that we can define function after main function provided we declared this function before main. Then how does main function see these functions after main function? Does the compiler first read the whole file and then run main() or sth?
You can think at the job of the compiler like this; it reads the source file token by token (not exactly line by line) and when sufficient tokens are read, it outputs the translation. It repeats that, until the source file is (correctly) finished: the job of the compiler is done.
For every token the compiler reads, it needs to know what the token represents. If it doesn't know, an error is generated.
So, while compiling your function
void function()
{
x += 3
}
it encounters an "x" but does not know what it represents (an integer? A float? Something else?). -error-.
Why do we need to declare global variables before function defining and declaring
Declaration and Definition are two different things. The compiler needs a declaration in order to know how to manage an identifier; the real definition can be somewhere else, even in another source (or already compiled) file.
And one more question. I know that we can define function after main function provided we declared this function before main. Then how does main function see these functions after main function? Does the compiler first read the whole file and then run main() or sth?
As explained before, all the compiler needs is a declaration, so it can output correct (object) code. If you declare function(), then define main(), then define function(), the compiler has enough to generate correct output, which will consist of code for main() and code for function() (we can say "in this order"). The next step, the linker, will take care to connect these two functions.
The definition of function() could also be absent: the compiler still would generate correct code for main(); the linker would instead complain, unless you tell it where to find the definition/implementation of function().
Also note that a definition is also a declaration. So if in your source you declare function() and then main(), you don't need forward declaration.
In the comments I've read that perhaps you are confusing interpreters with compilers - this is true, if you try to compare Python with C: very different beasts. A big difference is compiler vs interpreter, the compiler generates data (object code) but does not link it (and neither runs it). An interpreter instead is a compiler+linker+runtime, all packed together. Normally a compiler generates code that is much faster than the equivalent interpreted program, but to do this it needs accurate informations (precise types and declarations) and often (always?) is less versatile. The interpreter is often more versatile but it can not exploit all the optimizazions a good compiler can do.
Why do we need to declare global variables before function defining
and declaring since we call this variablefunction after this
declaration?
The c language is a strictly typed language. When the compiler processes an identifier it needs to determine its type to generate correct object code.
It is not necessary that a global variable used in a function shall be declared exactly before the function definition. But in any case it shall be declared before its usage in a function.
Here is a demonstrative program.
#include <stdio.h>
void function( void )
{
extern int x;
x += 3;
}
int x = 3;
int main( void )
{
function();
printf( "x = %d\n", x );
}
The program output is
x = 6
Here the variable x declared within the function refers to the global variable x defined after the function.
Then how does main function see these functions after main function?
Does the compiler first read the whole file and then run main() or
sth?
C is a compilation language. It does not run programs. It generates object code that then after some processing by the linker can be run.
In the point where a function is used what the compiler is need is the type of the function that to check whether the function is used correctly. If the function is an inline function then it can substitute its call for the function body It can rebuild the object code when the inline definition in the translation unit will be known.

Using functions with two seperate files

Files: A(main), B
I have learned that B's function can't be use in A without
funcntion definitions.
But my code ran normally with A, B files without function definitions
This is my code:
B.c
void a()
{
printf("hi");
}
A.c
#include <stdio.h>
void main()
{
a();
}
What is it? I'm confused.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
addendum...
sorry for my bad question.
my code works well with error.
but i couldn't see error.
but i have more question for difference between
'void a();'
'extern void a();'
Once upon a time, C did not require prior declaration of all functions. Many compilers still let you get away with this.
In file A.c, when you called
a();
where a was a function the compiler has never seen before, the compiler assumed that the declaration
extern int a();
was in scope. That is, the compiler assumed that a was a function taking unspecified arguments and returning int.
Or, that used to be the rule. That rule is no longer in C, so yes, you are supposed to explicitly declare all your functions before you call them. Most of today's compilers will warn you when they apply the old rule, and many aren't willing to apply the rule at all, or at least, not unless you use a non-default option flag requesting them to. But it sounds like your compiler is still willing to apply the rule without warning or error. That's great if you're compiling a bunch of very old code, but it's not so great if you're trying to learn modern C.
Now, in this case you have the additional problem that the actual definition of function a in file B.c defines it as returning void, not int, so theoretically that's wrong, too. But, in practice, the error of misdeclaring (or mis-calling) void- versus int-returning functions is an innocuous one, that doesn't cause any real problems. (It's still wrong, though, and worth avoiding.)
I think you know this, but a correct setup would either be to have file A.c look like this:
#include <stdio.h>
extern void a(void);
int main()
{
a();
}
or else to create the file B.h containing
extern void a(void);
and then to have file A.c look like this:
#include <stdio.h>
#include "B.h"
int main()
{
a();
}
(Note that I have also changed void main() to int main(), for correctness. If you're using an old compiler, as it sounds like you are, you may also have to add the line return 0; at the end of main().)
Addendum. You had also asked about that extern keyword. It has to do with the distinction between declarations and definitions. But this distinction plays out slightly differently for functions, versus global variables.
Declarations explain what type something has. Definitions explain what type something has, and they additionally allocate memory for the something, and supply its initial value.
These are declarations:
extern int i;
int f(int);
extern int f2(int, double);
These are definitions:
int i;
int i2 = 2;
int f(int x) { return 2 * x; }
int f2(int n, double x) { return n * x; }
The keyword extern explicitly says, "This is a declaration, the definition is somewhere else." For global variables, this makes a big difference. But for functions, when you say int f(int);, the compiler can tell, when it finds a , instead of a {, that this is a declaration (not a definition), so the keyword extern is optional in function declarations.
(Also, functions are always global in C; there are no local functions.)
See also section 4.2 and section 4.3 of these course notes.

How to over come the warning fun defined but not used

I am calling a function in one file
a = fun(a,b);
I am having the #define of that function in other file
#define fun fun1
I am defining that function in another file
static int fun1(int a, int b)
{
-------------
-------------
}
But compiler complaints
'fun1' defined but not used [-Wunused-function]
Its strange for me that compiler complaints about this.
static int fun1(int a, int b)
staticmeans that this function can be only used in this file. Remove the static and try again.
You have two problems here: The first about that warning, because in the other source file you don't actually use the function. The second problem is that you marked the function as static, which means that it will only be available in that specific source file.
If you want to be able to call functions defined in other source files (translation units as they are really called) then you can't make functions static.

Why is a function declared near the top of a source file?

I'm working through K & R to learn programming. Going well so far, but I'm unclear about the role of a line of code from section 1.8 (functions).
In section 1.8, the authors show you how to create a function to raise one integer to the power of another integer.
I've pasted the code below, as it was written in the book. Everything outputs fine. But I don't know why they've included this line at the top:
int power(int m, int n);
The book doesn't mention it, apart from saying that the program will raise integer m to the power n. If I remove the line from the code, the program still outputs as it should.
If I understand this correctly, the line
int power(int base, int n)
creates the function, and the braces underneath define the function. Then the braces under main call the function to output the chart.
So all that seems to make sense. But I don't see what the very top line does.
It could be extraneous, but it seems far more likely that I'm missing something. Can anyone enlighten me as to why that line is there?
#include <stdio.h>
int power(int m, int n);
/* test power function */
main()
{
int i;
for (i = 0; i < 10; ++i)
printf("%d %d %d\n", i, power(2,i), power(-3, i));
return 0;
}
/* power: raise base to n-th power; n >= 0 */
int power(int base, int n)
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i)
p = p * base;
return p;
}
The first line is the declaration of the function. The block of code at the bottom is the definition of the function.
Starting with the 1999 version of the ISO C standard, it's illegal (a constraint violation) to call a function without a visible declaration; the declaration must precede the call.
For a simple program like this one, you could just write the full definition of power() before the definition of main() (since a definition also provides a declaration), but for more complex cases (such as recursive calls) you often need to provide a separate declaration.
For larger programs, it's common to collect all the function declarations in a header file (foo.h, for example), and the corresponding definitions in a source file (foo.c, for example). A #include "foo.h" directive is used to make the declarations visible in other files. You'll see that kind of thing later in the book.
(In the 1990 and earlier versions of C, which is what K&R2 covers, there are cases where you can call a function without a visible declaration -- but it's still a very good idea to provide explicit declarations anyway.)
Incidentally, the declaration of the main program should really be int main(void) rather than just main().
Terminology: a "prototype" is a function declaration that specifies the types of the parameters.
int power(int base, int n); /* a declaration that's also a prototype */
int power(int, int); /* likewise */
int power(); /* a declaration but not a prototype */
(Parameter names are required in a definition, but optional in a standalone declaration.)
As a special case, a prototype for a function with no parameters uses (void), since empty parentheses already mean a non-prototype declaration. So int main(void) is a prototype, but int main() isn't.
Non-prototype declarations are "obsolescent", meaning that they could in theory be removed from a future language standard. But they've been obsolescent since 1989, and even in the new 2011 ISO C standard the committee hasn't seen fit to remove them.
int power(int m, int n);
is a declaration of the power function in its prototype form. A function declaration informs the compiler of the number of parameters the function has, the type of the function parameters and the type of the function return value.
In C you cannot use a function identifier before it has been declared.
It's a forward declaration which makes the function interface public as the function is used before it is actually implemented below main().
Header files, which you #include provide a similar functionality of making the callable API public---but the code is then commonly supplied in a library rather than via the same compilation unit as it is here in this single-file example of the K&R Intro chapter.
If you don't include that line at the top, when the program reaches power(2,i) in main power has not been declared yet. Programs are read from top to bottom, and by putting the declaration at the top, the compiler knows that "a definition is coming".
That line is just the function prototype. It's a forward declaration that allows code to be able to use some function with that signature that will exist when everything is linked together. Without it, the main() function will attempt to use the power() function but the compiler is not aware of it yet since it isn't actually defined later in the source file.
That line at the top that you are referring to is a function prototype. The ONLY thing it is there for is so that the compiler can check your work, that is, to make sure you are using the function correctly by passing the right types and number of arguments. That's all it is for. That is why you can remove it and the code still compiles - all you are doing by removing it is removing the compiler's reference so it can't check your work. And if you do remove it, then there is the possibility that you could pass the wrong type of argument(s) and cause a hard to find run time error or program crash. But leaving it in allows the compiler to flag such an error at compile time saving you some grief. And saving someone some grief is a good thing.
Later, with the C99 standard, they decided to make it mandatory to provide a function prototype (or else define the function first) in order for the code to compile, thus forcing you to let the compiler check your work.

Does the order of C objects matter?

Does the order in which C objects appear on the file matter?
For example, in functions, if I create two functions and the one above references the other one will it work? (Yes it will, I've tried it.)
Is the same in effect for static functions, INLINE functions, etc.?
Is the same in effect for structs? What happens if I reference a struct which is defined further down on the .c file?
Is this to any extend compiler-specific? How does the compiler work in this case? Does it first scan the whole file for all declarations/definitions and then attempts to dereference functions/symbols?
First, if by "if I create two functions and the one above references the other one will it work?" you mean something like this:
int foo()
{
return bar();
}
int bar()
{
return 0;
}
Then the compiler may do educated guesses at what bar() is, but it will at least spit a warning if bar() wasn't already declared. For symbols that can't be called (like variables or types), it's an outright error if they're used before they're declared.
In C, whenever you use an identifier (and no matter the kind of the identifier: it may be a function, a variable, a type, etc.), it should be declared beforehand. The various modifiers you may add to any identifier (like you said, static, inline and all the others) have no impact on this.
Do not confuse declaration and definition. A declaration is just telling the compiler that a name exists; a definition actually tells the compiler what it is.
For instance, this is a definition:
int bar() { return 4; }
Notice how it has a body, with (simple) code inside.
This is the matching declaration:
int bar();
The compiler will gladly accept the use of a function as soon as it sees either the declaration or the definition for it. For organization reasons and better flexibility, it's often better to write declarations for all your functions at the top of your C file (or inside an included header file) then the definitions.
So, my first example should look like this:
int foo();
int bar();
int foo()
{
return bar();
}
int bar()
{
return 0;
}
With the declarations above the C code, I can change the order of the functions in any way I like.
Typically something must be defined above where you use it. You can avoid this in different ways for different situations.
For functions, just provide a prototype above where it's called and all will be well.
int trol(int a, int b);
// use trol(int, int)
int trol(int a, int b) { }
If you have two functions, a and b, and they call each other and are defined in the order of: a, b, then you must provide b's prototype above the definition of a. a's prototype is not required because it is defined above where it is used inside b. Then the compiler will have no problems.
One other special case for functions is that you can use a function without declaring it and the compiler will try to infer the signature from the call. This answer explains it pretty well I think: Must declare function prototype in C?
For structs, you can use pointers to them before they are actually defined (but you can't access any of the fields) by providing a forward declaration:
struct s;
// use s*'s
struct s { };
(The above scenario facilitates recursive data structures like linked lists and trees; you can use pointers to structs before they are fully defined because the size of any type of pointer is constant.)
It matters, because if the compiler doesn't know what the function is - it will try to 'guess' (create a default int foo() prototype with matching parameters), and if your call is incorrect - you'll have mismatches (build errors, implicit castings, whatever).
It is common practice (if not even required) to declare the function before calling it (through prototypes aka forward declarations).
For functions with variable parameter lists (like printf) you must have a forward declaration for them to work properly. For example this code will not compile:
int foo(int a)
{
b(a);
b("hello", "kitty");
}
void b(int a, ...)
{
printf("%d", a);
}
But this - will:
#include <stdio.h>
int foo(int a)
{
return b(a);
}
int b(int a)
{
return printf("%d", a);
}
(with warning about the implicit forward declaration)
So in order to avoid dealing with the order of the objects in the file - use prototyping (forward declarations) to let the compiler know what's following.
From my experience, everything in C has to be written with the referenced "object" before the reference is made. I don't think this is specific to any compiler, but maybe there are some which I haven't found. Basically, everything always has to be:
Object Declaration
...
Object Reference

Resources