How does a forward declaration work? - c

I understand declaring factorial before main. But how can main calculate the answer when the factorial formula comes after it?
#include <stdio.h>
long long factorial(int);
int main()
{
int n;
long long f;
printf("Enter a number and I will return you its factorial:\n");
scanf_s("%d", &n);
if (n < 0)
printf("No negative numbers allowed!\n"); //prevent negative numbers
else
{
f = factorial(n);
printf("The factorial of %d is %ld\n", n, f);
}
return 0;
}
long long factorial(int n)
{
if (n == 0)
return 1;
else
return (n * factorial(n - 1));
}

But how can main calculate the answer when the factorial formula comes after it?
First thing — main does not calculate the answer; it's your factorial function which does it for you. Also there are 3 steps which I feel you need to know about when writing programs:
You write the code in a file.
You compile the file and the compiler checks for syntactical mistakes, no code calculation is happening in this phase its just mere lexical analysis.
Then linking takes place later. If you receive a linker error, it means that your code compiles fine, but that some function or library that is needed cannot be found. This occurs in what we call the linking stage and will prevent an executable from being generated. Many compilers do both the compiling and this linking stage.
Then when you actually run your code — it's then when the code's control flow goes into the factorial function when the calculation happens, i.e. at runtime. Use a Debugger to see this.
The below image is taken from Compiling, Linking and Building C/C++ Applications
From Wiki:
In computer programming, a forward declaration is a declaration of an
identifier (denoting an entity such as a type, a variable, a constant,
or a function) for which the programmer has not yet given a complete
definition....
This is particularly useful for one-pass compilers and separate
compilation. Forward declaration is used in languages that require
declaration before use; it is necessary for mutual recursion in such
languages, as it is impossible to define such functions (or data
structures) without a forward reference in one definition: one of the
functions (respectively, data structures) must be defined first. It is
also useful to allow flexible code organization, for example if one
wishes to place the main body at the top, and called functions below
it.
So basically the main function does not at all need to know how factorial works.

But how can main calculate the answer when the factorial formula comes after it?
The order in which a C program executes is only partially determined by the order in which the text appears.
For instance, look at the printf function you are using. That doesn't appear in your program at all; it is in a library which is linked to your program.
The forward declaration makes it known (from that point in the translation unit) that there is expected to exist such and such a function having a certain name, arguments and return value.
The simple answer is that your C program is processed from beginning to end before it begins to execute. So by the time main is called, the factorial function has already been seen and processed by the C compiler.
An address is assigned to the compiled factorial function, and that address is "backpatched" into the compiled main function when the program is linked.
The reason forward declarations are needed at all is that C is an old-fashioned language originally designed to allow one-pass compilation. This means that the compiler "translates as it goes": functions earlier in a translation unit are compiled and emitted before later functions are seen. To correctly compile a call to a function which appears later (or, generally, appears elsewhere, like in another translation unit), some information must be announced about that function so that it is known at that point.

It works in this manner: let's take an example to find factorial of 3
Recursion :
As factorial of 0 is 1 and factorial of 1 is also 1, so you can write like
if(n <= 1)
return 1;

Since in main function when compiler sees this f = factorial(n); function, the compiler has no idea of what it means. it doesn't know where the function being defined, but it does know the argument the function is receiving is correct, because it's a user defined function that has its definition after main function.
Hence there should be some way to tell the compiler that I am using a function with name factorial which returns long long with a single int argument; therefore you define a prototype of the function before main().
Whenever you call the function factorial the compiler cross checks with the function prototype and ensures correct function call.
A function prototype is not required if you define the function before main.
Example case where function prototyping is not required :
/*function prototyping is not required*/
long long factorial(int n)
{
//body of factorial
}
int main()
{
...
f=factorial(n);
...
}
Here, the compiler knows the definition of factorial; it knows the return type, the argument type, and the function name as well, before it is called in main.

Related

Why do we need return type and parameter type in funtion declarations? [closed]

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 6 days ago.
This post was edited and submitted for review 6 days ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I've been told we somehow need them so the compiler can continue onwards without having read the definition yet.
Somehow we need them in order for the program to work properly, to avoid conflicts between functions.
Please explain.
If you're going to have separate compilation, meaning that the call versus the definition of a function might be in separate source files, compiled at different times, perhaps months or years apart, you need to decide how information passed to and returned from the function is going to be coordinated.
Let's cover the return value first. Functions can be declared to return int, or double, or char *, or just about any of C's other types. (There are one or two exceptions, types which it's impossible to return, but they needn't concern us here.) But for any given ABI, different values get returned in different ways. Integers and pointers might get returned in a general-purpose processor register. Floating-point values might get returned in a floating-point register. Structures might get returned in some specially-designated memory area. In any case, the called function is going to do the returning, but the calling function (compiled separately) is going to do something with the returned value, so it has to know how to emit the right code to do that. And the only way for it to know (again, under C's separate-compilation model) is the function declaration that indicated the return type. If the calling code thought the function was going to return an int, but the called function actually returned a double, it just wouldn't work, because the called function would place its return value in the spot where return values of type double go, and the calling code would fetch a value from the place where return values of type int go, and it would get indeterminate garbage instead.
Now let's talk about the arguments passed to the function. Again, the mechanisms behind argument passing can take several forms, depending on the type(s) of the argument(s). Again, mismatches are easy, but can cause serious problems. If the programmers writing calling code could be relied on to always pass the correct number of arguments, and of the correct types, we wouldn't need function prototypes — and indeed, that's how C was for the first few years of its life. These days, however, that risk is generally considered as unacceptable, and function prototypes are considered mandatory — by the language standard, by compilers, and by most C programmers. (You might still find a few holdouts, grumbling that prototypes are newfangled or unnecessary, but they're basically an ignorable minority.)
There's a remaining wrinkle concerning "varargs" functions such as printf. Since they don't accept a fixed number of fixed-type arguments, they can't have a prototype that specifies the types of those arguments in advance. An ellipsis ("...") in a function prototype indicates variable arguments that (a) can't be enforced by the compiler but that (b) do have the default argument promotions performed on them, to provide a little more regularity (basically, small types like char and int promoted to int, and float promoted to double). Varargs functions, too, are generally consider old-school and risky if not downright dangerous, and are not recommended for new designs, unless perhaps if they follow the pattern of printf, meaning that the compiler can peek at the format string (if constant) and do the programmer the favor of double-checking the arguments.
The requirements here have been evolving ever since C was invented, and (as discussed in the comments) are still changing. If you have specific questions about what's legal and what's not, what works and what won't, you might want to ask them explicitly, but the answer may depend on which version of C we're talking about.
We can get a good picture of most of the issues just by looking at the standard sqrt function. Suppose you say
double x = sqrt(144);
Once upon a time, that was doubly wrong. Once upon a time, without a function declaration in scope, sqrt would be assumed to return int, meaning that this call wouldn't work, because sqrt actually returns a double. (The compiler would emit code to fetch an int and convert it to the double required by x, but this would be meaningless since there's no int actually returned by sqrt to convert.) But, there's a second problem: sqrt accepts a double argument, which this code doesn't pass, so sqrt wouldn't even receive the correct value to take the square root of.
So, once upon a time, you absolutely needed
extern double sqrt();
(which you probably got from <math.h>) to tell the compiler that sqrt returned a double, and it was your responsibility to call
double x = sqrt(144.);
or
double x = sqrt((double)144);
to cause a double value to be passed.
Today, if you call sqrt out of a clear sky (that is, without a declaration in scope), the compiler is more likely to complain that there's no prototype in scope — that is, it will not quietly assume that sqrt returns int. And if there is a declaration in scope, it will be the prototype declaration
extern double sqrt(double);
which explicitly says that sqrt expects one argument of type double. So, today, the code
double x = sqrt(144);
works fine — the compiler knows to implicitly convert the int value 144 to double before passing it to sqrt.
If you did something really wrong, like calling sqrt(44, 55), in the old days you'd get no complaints (and a very wrong answer), while today you'll get an error saying you've passed too many arguments.
This is probably a longer answer than you were looking for, but in closing, there are two final points to make:
No one would claim that any of this makes perfect sense, or is the way you'd design things from scratch, today. We're living (as ever) with a number of imperfect compromises between modernity and backwards compatibility.
The "guarantees" apparently promised by function prototypes — namely, that automatic argument conversions will be performed if possible, and that compile-time errors will be emitted for gross mismatches — are not absolute, and still depend on a certain amount of programmer care, namely to ensure that the prototypes (upon which everything depends) are actually correct. This generally means putting them in .h files, included both by the caller and the defining source file. See also this question exploring how those vital conventions might be enforced.
Because C Compilers compile code row from top to bottom. If you gonna use any function in your main function you have two ways to do that.
You can code your function first then use main(Compiler code row from top to bottom so it will figure out there is a function)
Like you do you can use parameters to say "Hey there is a function that i made i will use that later" to Compiler.
Example:
Declaration without parameters. COMPILES.
Declaration without parameters and either without type. COMPILES BUT WARNING.
Call BEFORE definition (and no declaration). Compile error. ERROR.
Compiles perfectly (as #Vlad from Moscow pointed, neither parameters are needed in declaration):
1 #include <stdio.h>
2
3 int sum (); // no parameters declaration (if also omit type int, will compile but with warning
4
5 int main (void)
6 {
7 int numa = 2, numb = 3;
8
9 printf ("Sum %d + %d = %d\n", numa, numb, sum ( numa, numb ));
10
11 return 0;
12 }
13
14 int sum ( int numa, int numb )
15 {
16 return numa + numb;
17 }
output:
./ftype_def_dec
Sum 2 + 3 = 5
type int of function ommited (compiled but with warning):
gcc -o ftype_def_dec ftype_def_dec.c
ftype_def_dec.c:3:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
sum ();
^
1 warning generated.
Does not compile (if you omit declaration in a function called in main() BEFORE it's DEFINITION [every detail [types & what/how it does explicited]]):
1 #include <stdio.h>
2
3 // int sum ();
4
5 int main (void)
6 {
7 int numa = 2, numb = 3;
8
9 printf ("Sum %d + %d = %d\n", numa, numb, sum ( numa, numb ));
10
11 return 0;
12 }
13
14 int sum ( int numa, int numb )
15 {
16 return numa + numb;
17 }
gcc -o ftype_def_dec ftype_def_dec.c
ftype_def_dec.c:9:44: error: implicit declaration of function 'sum' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
printf ("Sum %d + %d = %d\n", numa, numb, sum ( numa, numb ));
^
1 error generated.
Because the compiler has to be able to know how your function can be called and used (i.e. what parameters it accepts and what its return type is (although the former can be omitted)) in other calling functions (such as in main).
As mentioned by another answer, the compiler will compile your program from top to bottom. Thus, when it reaches a given line in your program where you use your function, if you had not previously declared it, it would not know how to parse and compile that statement, and/or be able to detect if it consists of an error.
Take a simple example:
void square(int*);
int main(void) {
int number = 4;
number = square(number); // ERROR
// correct usage would be:
square(&number);
return 0;
}
void square(int *num) {
if (!num)
return;
*num *= *num;
}
However, if you had not declared square before main, the compiler would have no way of knowing what do with your call to square inside main, or which of the two calls was an error.
In other words, square is an undeclared identifier if you have not declared the function before calling it.
Just like you cannot do something like:
int main(void) {
int x = 2;
y = x + 5; // ERROR: undeclared identifier 'y'
int y;
return 0;
}
... because the compiler has no idea what y is by the time it reaches its first usage.

callback function confusion in general

I am very confused about callback function. Specifically I am confused about the order of the functions being called in the sequence of functions that make use of callback functions.
For example, I have this piece of code and problem in a question that I recently done, and the solution is below:
The procedure nthPrime shown below computes the nth prime number asynchronously; i.e., it returns
immediately and then calls callback sometime later with the value of the requested prime number. Give
code below that uses this procedure to print the product of the 100th and 200th prime numbers without spinwaiting
or polling (i.e., your code must call this procedure twice and multiply the results). You can use global
variables in your solution if you like.
void nthPrime(int n, void (*callback)(int));
So the solution is:
int t;
void nthPrime(int n, void (*callback)(int));
void foo(int n) {
nthPrime(100, a);
}
void a(int p) {
t = p; // why assign p to t here?
nthPrime(200, b);
}
void b(int p) {
printf("%d\n", t * p); // t*p, but what is p here?
}
However I am totally confused about how the solution (or functions above is being used to implement the request to print the product of the 2 primes).
I guess foo() is being called first. Then I am kind of lost how the sequences is being called (I know some functions return right-away and wait for the result of the "call-back" function to finish???). I am confused what is being returned right away, and what will be run in a near future to return something later in the sequences.
When you call nthPrime(100, a);, nthPrime will calculate the 100th prime, and then call the a function.
When it calls a, p will be that 100th prime.
a then calls nthPrime(200, b);. nthPrime will calculate the 200th prime, then call the b function.
When it calls b, its local variable p will be that 200th prime.
b needs to multiply the prime that it received by the 100th prime that was received by a. It's not possible to access variables in another function's scope directly. That's why a copies its parameter to the global variable t -- this provides the communication between the two callback functions.
In many other languages this would be done with closures rather than global variables, but C doesn't have closures. This limits the flexibility and capability of callbacks in C.

Whether frama-c can get the range of variables before a particular program code

int main()
{
int B = 1;
int x = rand()%10+1;
int x1 = rand()%10+1;
int A = 1;
while((B <= 5))
{
B++;
A++;
if(B == x)
{
return 0;
}
}
task(A) //The variable A passes in the range of values before the task function
A = -2;
return 0;
}
/*How can I use frama-c to get the range of A at task code if I want to get the range of A at task statement position instead of the range of A at the end of the program execution*/
How can I use frama-c to get the range of A at task code if I want to get the range of A at task statement position instead of the range of A at the end of the program execution
If I understand your question well, you would like to know the interval of variation of A at a specific statement. I assume that you're are relying on the Eva plug-in, as it is the kind of information that is typically given by Eva (at least if I interpret well "instead of the range of A at the end of the program execution").
There are two possibilities. The first one is to use the programmatic API of Eva, namely the Db.Value module. This requires knowledge of OCaml and reading the Frama-C developer manual, but is the most flexible and stable way to access the information. Briefly speaking, Db.Value.get_state will, as its name suggests, return the abstract state computed after a run of the Eva analyzer, for the statement given as argument, while Db.Value.eval_expr, will, given an abstract state and an expression, compute the abstract value of the expression in the corresponding state.
The second possibility is to use the Frama_C_show_each_* family of built-in functions: whenever Eva encounters a function whose name starts with Frama_C_show_each_, it will print on the standard output the abstract value of the arguments given to the function in the current abstract state. Hence, adding Frama_C_show_each_A(A); before the call to task(A) will give you, with frama-c -eva test.i, among other things
[eva] test.i:19: Frama_C_show_each_A: [1..2147483647]
Note that I've modified your code in order to let it run properly with Frama-C:
added prototype extern int rand(void); and extern void task(int);
added a ';' after task(A)
Please ensure that you provide a minimal, complete and verifiable example with your questions, this makes them much, much, easier to answer

'system' was not declared in this scope error

So i dont get this error in other programs but i did get it in this.
This program is an example where i dont get the error.
#include<stdio.h>
int main() {
system("pause");
} // end main
but in this program below i get the error
#include <stdio.h>
//#include <stdlib.h>
// Takes the number from function1, calculates the result and returns recursively.
int topla (int n) {
if(n == 1)
return 3;
else
return topla(n-1) + topla(n-1) + topla(n-1);
}
// Takes a number from main and calls function topla to find out what is 3 to the
// power of n
int function1(int n) {
return topla(n);
}
int main() {
int n; // We us this to calculate 3 to the power of n
printf("Enter a number n to find what 3 to the power n is: ");
scanf("%d", &n);
function1(n);
system("pause");
} // end main
Just include stdlib.h, but don't use system("pause") as it's not standard and will not work on every system, just a simple getchar() (or a loop involving getchar() since you've used scanf()) should do the trick.
And normally system("pause") is found in windows command line programs because windows command prompt closes when the program exits, so maybe running the program from the command prompt directly would help, or using an IDE that fixes this like geany.
Finally always check the return value if scanf() instead of assuming that it worked.
Note: This code
return topla(n - 1) + topla(n - 1) + topla(n - 1)
you can write as
return 3 * topla(n - 1);
instead of calling topla() recursively 3 times.
And you don't really need the else because the function returns unless the n != 1 so even without the else the recursion will stop when n == 1.
The system function is declared in the standard header <stdlib.h>. If your program calls system(), you must have
#include <stdlib.h>
at or near the top of your source file.
But part of your question is: why didn't the compiler complain when you omitted the #include directive?
The 1990 C standard (sometimes called "ANSI C") permits calls to functions that have not been explicitly declared. If you write, for example:
system("pause");
with no visible declaration for the system function, it would be assumed that system is declared with a return type of int and parameters matching the arguments in the call -- in this case, a single argument of type char*. That happens to be consistent with the actual declaration of system, so with a C90 compiler, you can get away with omitting the #include directive. And some C compilers that support the more current 1999 and 2011 standards (which don't permit implicit declarations) still permit the old form, perhaps with a warning, for the sake of backward compatibility.
Even given a C90 compiler, there is no advantage to depending on the now obsolete "implicit int" rule. Just add the #include <stdlib.h>. More generally, for any library function you call, read its documentation and #include the header that declares it.
As for why you got an error with one of your programs and not another, I don't have an explanation for that. Perhaps you invoked your compiler with different settings. In any case, it doesn't really matter -- though you might look into how to configure your compiler so it always warns about things like this, so you can avoid this kind of error.
Here you need to know about two things.
Firstly, your code works absolutely fine and the program really finds the value of 3^n. So do not worry about that.
Coming to the system() part,
In order to use the system(); function, you need to include the stdlib.h header file, as the function is declared in that header.
So it is a good practice to include the header (rather than commenting it).
Now, the pause keyword is used in windows, to stop the console from closing after the completion of the program and it is only for windows.
Note that, system("pause"); is also not a standard, and it does not work on other machines, namely linux as, with the system command, you are directly interacting with the command line. In this regard, the commands for each operating system are specific, and they cannot be used for other OS.
so it is better that you use getchar(); , a C standard library function, to hold the console window.

What is the difference between the two locations?

I have a recursive program. When the printf is used in the function, it outputs 123 and when used outside, it outputs 0123 .
#include <stdio.h>
fact(int);
int main()
{
int x=3;
fact(x);
printf("\n");
system("PAUSE");
}
int fact(int y)
{
if (y > 0)
{
fact(y-1);
printf("%d",y);
}
//printf("%d",y);
}
I am not using both the printf at the same time . What difference does the location of this printf statement create?
Since your if condition looks for the values greater than zero, it is working as expected.
When the printf outside that IF block is used, it gets executed even when y is 0, which is not the case for the printf inside the IF block.
fact(int) is called by following sequence,
fact(3)-->fact(2)--->fact(1)--->fact(0)
The last call is fact(0). According to the implementation of fact(int), when 0 is passed in, 0 is printed if printf() is used outsite. 0 is not printed if printf() is used inside.
In fact, all the values passed into fact(int) is printed when printf() is used outsite.
I'd say one reason you didn't see the answer yourself is because your code is sloppy. Here are some complaints:
Your functions have no explicit return statements which are
especially important for understanding recursive code.
system() requires stdlib, but stdlib.h isn't included.
system("PAUSE") is unportable and unnecessary. Actually your code
would not run on my system because of this. See:
http://www.gidnetwork.com/b-61.html
Your question looks like homework, so this one is the homework's fault and not yours: because n! grows so quickly, factorial functions using 'int' for the return type can only calculate n! for 1<=n<=12, which is useless.
Try this exercise: write a one-line factorial function using a single return and a conditional assignment.

Resources