Passing parameters to function in different file (gcc) - c

I wrote an add function for int in Add.c. Then, I passed real numbers to this add function in Main.c. The codes are shown as follows.
If I have declaration of add function before calling it, the answer is correct as 30. However, if the declaration does not exist, the answer is incorrect. Why?
Add.c
int add(int x, int y) { return x + y;}
Main.c
#include<stdio.h>
int add(int, int); // If this does not exist, the answer is not 30.
int main(void) {
printf("%d\n", add(10.5, 20.5));
}

Without the declaration, which is more specifically a prototype (a declaration with specified parameter types), you're relying on an implicit prototype-less declaration of the function (which is now an obsolescent feature of C).
The implicit prototype for function f is int f()—a function returning int and taking an unspecified number of parameters.
The way functions without prototypes are called is the arguments are promoted (lesser than int integer types to int and floats to doubles) and passed to the function in an implementation-defined way. If the arguments don't match the definition, the behavior is undefined (your case).
You could fix this (while still relying on the implicit declaration) by providing explicit casts:
#include<stdio.h>
//nothing (probably will get a compiler warning) or
int add(); /*=params unspecified*/
int main(void) {
printf("%d\n", add((int)10.5, (int)20.5));
}
thereby removing the UB (undefined behavior), or you can include the prototype as you have, which will make the compiler convert passed-in floats to match the expected types (int). In other words, with the prototype, the compiler will insert these casts for you, seeing that a conversion from float to int in (argument) assignment.
The preferred way to solve this is with a prototype included via a header which is also included in the implementation file (Add.c) so as to allow to compiler to verify the call is consistent with the definition.

To make this work, first of all, you have to include the "add.c" file into the "main.c". Coz main.c doesn't know about "add" function in add.c. (Also you should not make '.c' file to add a function or something. Instead use '.h')
Now the solution should look like this...
add.h
int add(int x, int y){
return x + y;
}
main.c
#include<stdio.h>
#include "add.h"
int main(void){
printf("%d\n", add(10, 20));
return 0;
}
Make sure to keep both the files in same directory.

Before using add in Main.c, it needs to know the declaration for this function. Without using function prototype in this case the behavior of the program would be undefined. You can either add a prototype before main as you did or you can create a separate Add.h file and put the prototype there.
In second case you need to add Add.h to both .c files.
Add.h
#ifndef ADD_H
#define ADD_H
int add(int x, int y;
#endif
Add.c
#include "Add.h"
int add(int x, int y) { return x + y;}
Main.c
#include<stdio.h>
#inclide "Add.h"
int main(void) {
printf("%d\n", add(10, 20));
}

Related

Cannot print called float variables

I cannot print float variables when calling my functions. int variables print but floats won't print their proper value when passed to my function.
I tried to change the float to int and that worked
int main() {
int foo = 6;
call(foo);
}
void call(int bar) {
printf("%d", bar);
}
This worked and it does indeed print 6.
But, doing the same but with floats only prints out 0.00000:
int main() {
float foo = 6;
call(foo);
}
void call(float bar) {
printf("%f", bar);
}
How do I correctly call and then print float variables?
you need a forward declaration of call
void call(float integerrrr);
int main(){
float integerrrr=6;
call(integerrrr);
}
void call(float integerrrr){
printf("%f", integerrrr);
}
your compiler probably warned you about this
You could simply define call above main instead of below it. The compiler must have seen the declaration of functions when they are used, so a forward declaration like pm100 suggests is one way. Moving the whole definition above main is the another (that does not require a forward declaration).
#include <stdio.h>
void call(float integerrrr){
printf("%f", integerrrr);
}
int main(void){
float integerrrr = 6;
call(integerrrr); // now the compiler knows about this function
}
INT type variables i can print but float just does not
If your program actually compiles as-is it will use an old (obsolete) rule that makes an implicit declaration of undeclared functions when they are used. The implicit declaration would be int call(); - which does not match your actual function. The program (even the one that seems to be working) therefore had undefined behavior.
the compiler of c work from top to bottom so line by line,
so u will have to call the first function void call() then your main function:
void call(float integerrrr){
printf("%f", integerrrr);
}
int main(){
float integerrrr=6;
call(integerrrr);
}

Example of extern global variable - Error

I'd like to understand which mistake i did in the following example. There are three file: main.c, libreria_mia.c and libreria_mia.h.
// main.c
#include <stdio.h>
#include "libreria_mia.h"
int x = 5;
int main()
{
int y = quadrato();
printf("%d\n", y);
return 0;
}
// libreria_mia.h
extern int x;
int quadrato(void);
// libreria_mia.c
int quadrato(void)
{
x = x * x;
}
Error:
libreria_mia.c:5:2: error: ‘x’ undeclared (first use in this function)
Thank you for your time.
When you compile libreria_mia.c, the compiler does not automatically know about libreria_mia.h or the declarations within it. To provide a declaration for x while compiling libreria_mia.c, libreria_mia.c must include a header that declares x or have a declaration of x directly in libreria_mia.c.
Additionally, it is conventional for a header named file.h to declare things defined in file.c (not necessarily all things defined in file.c, just those intended to be used outside it). But you have x declared in libreria_mia.h but defined in main.c. Normally, one would either define x in libreria_mia.c or declare it in main.h, and usually the former as main.c is more commonly a user of all other things in the program rather than a provider.

It gives me error "conflicting typer for 'mysqrt'"

#include <stdio.h>
#include <math.h>
float mysqrt (float x)
{
float y;
x=x-1;
y= 1+(x/2)-(pow(x,2)/2)+(pow(x,3)/8)-(5*pow(x,4)/128);
return y;
}
int main()
{
printf("%f",mysqrt(5));
}
I searched older answer in this website and tried to use them but still I cant figure out why it doesnt work
I don't think the code you have posted is quite accurate.
You are probably calling mysqrt() before you have provided a declaration of the function. In old versions of the C standard (C89), this was allowed and the function would be given an implicit declaration of:
int mysqrt();
That is, a function taking an unknown number of non-variadic parameters, and returning int. This clearly contradicts the actual definition of the function.
In more recent versions of the standard (C99/C11), the compiler is required to produce a diagnostic message if you try to call a function that has not been declared.
You should change your code so that the function definition appears before the function call, or provide a function declaration before the function call. Eg:
float mysqrt (float);
int main()
{
printf("%f",mysqrt(5));
}
float mysqrt (float x)
{
/* Function body */
}

C language - calling functions without function prototype

I found here that function prototype is necessary before function call if the function is below function calling.
I checked this case in gcc compiler and it compile code without function prototype.
Example:
#include <stdio.h>
//int sum (int, int); -- it runs with this commented line
int main (void)
{
int total;
total = sum (2, 3);
printf ("Total is %d\n", total);
return 0;
}
int sum (int a, int b)
{
return a + b;
}
Could explain somebody this issue?
When you don't provide a function prototype before it is called, the compiler assumes that the function is defined somewhere which will be linked against its definition during the linking phase. The default return type is assumed to be int and nothing is assumed about the function parameter. This is called implicit declaration. This means that the assumed function signature here is
int sum();
Here, the empty parameter list means the function sum takes a fixed but unknown number of arguments all of which are of unknown types. It is different from the function declaration
int sum(void);
However, in C++, the above two declarations are exactly the same. If your function has a return type other than int, then the assumed function signature won't match and this will result in compile error. In fact, it's an error in C99 and C11. You should always provide function prototype before it is called.
It says on this page that: " You don't have to declare the function first, but if you don't, the C compiler will assume the function returns an int (even if the real function, defined later, doesn't)."
It is confirmed here.
As for arguments: "and nothing is assumed about its arguments."
I changed your code to #include
/* int sum (int, int); -- it runs with this commented line */
int
main (void)
{
int total;
total = sum (2, 3);
printf ("Total is %d\n", total);
return 0;
}
int
sum (int a, int b)
{
return a + b;
}
Then compile with:
gcc --std=c90 -ansi -pedantic node.c
Also i try with some standard but may be it's related to gcc version and C standard.

Can functions declared in main access variables declared in main?

I have an array that I declared and initialized in main called Edges.
I have also declared some functions in main that access the array called Edges.
The code compiles and works.
Why does it work? I thought variables declared in main aren't global.
Edit: see Sourav's code.
Actually, if you declare a function inside a function, the inner function is just visible to the outer function and NOT in global scope. So, the variables declared by you and the inner function [to be appropriate, the code block] is having same scope. Hence, no issues accessing the variable.
Check this one
code
#include <stdio.h>
#include <stdlib.h>
int innerfunc();
int main()
{
int outer = 5;
int innerfunc()
{
printf("outer is %d\n", outer);
}
innerfunc();
return 0;
}
output
[sourav#infba01383 so_overflow]# ./a.out
outer is 5
[sourav#infba01383 so_overflow]#
You can't declare a function inside a function in C. This means that you can't declare function(s) inside main. Compile your code with -pedantic flag and you will see this warning for sure;
[Warning] ISO C forbids nested functions [-Wpedantic]
I compiled this code
#include <stdio.h>
void void print(int *);
int main()
{
int a[2] = {1,3};
void print(int *a)
{
printf("%d", *a);
}
print(a);
return 0;
}
and getting the warning
[Warning] ISO C forbids nested functions [-Wpedantic]
First of all, as most answers have mentioned, it is a gcc extension; not part of standard C.
Below answer is strictly confined to gcc.
gcc does treat them as any other function.
e.g. Check below code:
(I took liberty to extend your code as below:)
#include <stdio.h>
#include <stdlib.h>
typedef int operation(int num1, int num2); // for function pointer...
operation* getOperation(char oper)
{
int a=10;
int add(int x, int y){return x+y+a;}
int sub(int x, int y){return x-y+a;}
int nop(int x, int y){return a;}
if(oper=='+')return add;
if(oper=='-')return sub;
return nop;
}
int main()
{
operation *my_op;
my_op=getOperation('+');
printf("%d\n",my_op(5,3));
my_op=getOperation('-');
printf("%d\n",my_op(5,3));
return 0;
}
If you compile it with gcc -S & check the assembly code generated, it would show that
The functions - getOperation & main - are converted to assembly, without any name change. Thus these can be called from any function (in this or even from other file).
e.g.
.globl getOperation /*This line will be missing in case of static functions.*/
.type getOperation, #function
The functions - add, sub, nop - are converted to assembly with some unique random suffix.
e.g.
/*No .globl line is printed here.*/
.type add.2685, #function
Since the names are changed, you cannot call them from other functions. Only the 'parent function' (getOperation in this case) has the information of the function name. (Check for c variable scope for more details.)
However, you can use them in other functions, using function pointers, as shown in code above.
Regarding the local variables in getOperation (a for example): They are accessed from add/sub/nop using rbp register.
HINT: Compile a small code having 'local functions' with gcc -S, to understand what's exactly going on.. :-)
Nested function (annonymouse functions) are not a part of the c standard library, there is an extension which can be used.
You may declare global variables and use them throughout your programs also.
Sourav is correct actually, you may declare the function but its scope is limited to main

Resources