Function declaration before and after main() - c

#include <stdio.h>
int add2nums( int, int);
void main(void)
{
int y,a,b;
printf("Enter 2 numbers\n");
scanf("%d%d", &a, &b);
y = add2nums(a,b);
printf("a is %d\n", a);
printf("b is %d\n", b);
printf("y is %d\n", y);
}
int add2nums( int num1, int num2)
{
int sum;
sum = num1 + num2;
return(sum);
}
So usually, when I create new functions in C the definition of the function is created before the main() function.
In my lecture, there is this example of how to create a function prototype and how they are created by declaring it before the main() function and then defining it after the end of the main() function.
When running the program above, the following error comes up:
Line5: warning: return type of 'main' is not 'int' [-Wmain]|
What is happening? And why is the declaration of the function add2nums() occur twice once before main() and with no parameters?
int add2nums( int, int);
and then again after the end of main() with parameters num1 and num2
int add2nums( int num1, int num2)

There are two valid signatures for the main() function:
int main( void )
int main( int argc, char *argv[] )
Notice that both valid signatures have a return type of int. Any other return type, such as void is not valid and causes the compiler to output a warning message.
When the code calls a function, the compiler needs to know the signature of that called function. There are two ways to tell the compiler what the signature of the called function is:
have the whole function listed before where it is called
have a prototype (aka forward reference) of the function signature before where the function is called. In a prototype the compiler only needs the returned type and the types of the parameters. However, it is a good programming practice to have the names of the parameters listed in the prototype as a courtesy to the humans reading the code.

In C language, the main function has a signature int main(), which lets you to return a value back to the OS, but you made the main() with no void return type. Because of that you've got the warning.
int add2nums( int, int); is just a declaration of the function which lets the compiler make a reference to the function. That's because the compiler reads the file only once.
Names of the parameters aren't required, because they aren't part of the signature.

Declaration of the function is the information for the compiler (not linker as another answer states) - what type the parameters of the function are and what type of the return value is.
So the names of the parameters are not needed.

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);
}

const-qualifier with typedef-ed function pointer

What does the C standard have to say regarding typedef-ed function pointers being const qualified in parameters to functions? For example, say I have the following type
typedef int (*Operation)(int a, int b);
I've got a bunch of operations which take two ints, performs the operation, and then returns an int. Then I have a function which performs the actual function pointer call.
int doOpOnce(const Operation op, int a, int b)
{
return op(a, b);
}
I want to guarantee that the function pointer doesn't change during the doOpOnce call and I also want to document to users of doOpOnce that it will actually call the function given to it. Is this valid? Is there any difference between:
int doOpOnce(const Operation op, int a, int b)
int doOpOnce(Operation const op, int a, int b)
Finally, here is an example. Its compiled with gcc 4.9.2 with flags -std=c99 -Wall -Wextra -pedantic and it correctly errors when I try to change my const function pointer.
#include <stdio.h>
typedef int (*Operation)(int a, int b);
int opAdd(int a, int b)
{
return a + b;
}
int opSub(int a, int b)
{
return a - b;
}
int doOpOnce(const Operation op, int a, int b)
{
op = opSub; // error: assignment of read-only parameter 'op'
return op(a, b);
}
int main()
{
printf("%d\n", doOpOnce(opAdd, 10, 20));
return 0;
}
I do not want to add the const qualifier to the Operation typedef as I have other functions which CAN modify Operation pointers. I just want stronger typing in some circumstances.
If the parameter type is Operation, the caller passes a copy of the pointer into the function and so the function can't actually change where that pointer is pointing back in the caller. Adding the const keyword here would just be a defensive technique in the implementation that prevents you from reassigning your local copy. In that sense, you probably don't even need the const qualifier to signal anything to the client of your library.
To address your other question, the two placements of const have the same meaning, so you can pick whichever one you'd like.
Let the outside world (.h) see int doOpOnce(Operation op, int a, int b); and your .c file implement int doOpOnce(Operation const op, int a, int b) { so "to guarantee that the function pointer doesn't change during the doOpOnce"
"I also want to document to users of doOpOnce that it will actually call the function given to it. " belongs in the code documentation.
A function declaration signature of int doOpOnce(Operation const op, int a, int b); is not sufficient to guarantee "it will actually call the function given to it".
For the user of the function doOpOnce it is unimportant whether the pointer to function declared with the const qualifier or not because the function deals with a copy of the original pointer supplied by the user as an argument.
For the user of the function these two function declarations
int doOpOnce(const Operation op, int a, int b);
and
int doOpOnce( Operation op, int a, int b);
declare the same one function. You may include the both declarations in the program.
It is only within the function definition you will not be able to change this pointer that is a local variable of the function as any its parameter.
.

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.

Declare a void function in C

I am learning C and I am studying functions. So, I read that when I implement my own function I have to declare it before the main(). If I miss the declaration the compiler will get an error message.
As I was studying this example (finds if the number is a prime number),
#include <stdio.h>
void prime(); // Function prototype(declaration)
int main()
{
int num, i, flag;
num = input(); // No argument is passed to input()
for(i=2,flag=i; i<=num/2; ++i,flag=i)
{
flag = i;
if(num%i==0)
{
printf("%d is not prime\n", num);
++flag;
break;
}
}
if(flag==i)
printf("%d is prime\n", num);
return 0;
}
int input() /* Integer value is returned from input() to calling function */
{
int n;
printf("\nEnter positive enter to check: ");
scanf("%d", &n);
return n;
}
I noticed that a function prime() is declared, but in the main, a function, input(), is called and also the function input() is implemented at the bottom. Ok, I thought it was a mistake and I change the name from prime to input.
However if I delete the declaration and I don’t put any there, the program is compiled without errors and it runs smoothly. (I compile and run it on Ubuntu.)
Is it necessary to declare a void function with not arguments?
If you don't have a forward declaration of your function before the place of usage, the compiler will create implicit declaration for you - with the signature int input(). It will take the name of the function you called, it will assume that the function is returning int, and it can accept any arguments (as Bartek noted in the comment).
For this function, the implicit declaration matches the real declaration, so you don't have problems. However, you should always be careful about this, and you should always prefer forward declarations instead of implicit ones (no matter if they are same or not). So, instead of just having forward declaration of the void prime() function (assuming that you will use it somewhere), you should also have a forward declaration of int input().
To see how can you pass any number of the arguments, consider this:
#include <stdio.h>
// Takes any number of the arguments
int foo();
// Doesn't takes any arguments
int bar(void)
{
printf("Hello from bar()!\n");
return 0;
}
int main()
{
// Both works
// However, this will print junk as you're not pushing
// Any arguments on the stack - but the compiler will assume you are
foo();
// This will print 1, 2, 3
foo(1, 2, 3);
// Works
bar();
// Doesn't work
// bar(1, 2, 3);
return 0;
}
// Definition
int foo(int i, int j, int k)
{
printf("%d %d %d\n", i, j, k);
return 0;
}
So, inside the definition of the function you're describing function arguments. However, declaration of the function is telling the compiler not to do any checks on the parameters.
Not declaring a prototype and relying on default argument/return type promotion is dangerous and was a part of old C. In C99 and onward it is illegal to call a function without first providing a declaration or definition of the function.
my question is, is it necessary to declare a void function with not arguments?
Yes. For this you have to put void in the function parenthesis.
void foo(void);
Declaring a function like
void foo();
means that it can take any number of arguments.
If prime is not used, then omit the declaration.
The code won't compile as C++, because the compiler would complain that function input is used but not declared. A C compiler might issue a warning, but C is more relaxed and does an implicit declaration of input as int input() which means that you can pass any value to input and input returns an int.
It is good style to always provide a function declaration before using the function. Only if you do this the compiler can see if you are passing too few, too many or wrongly typed arguments and how to correctly handle the return value (which might be short or char instead of int).

Function inside function in C

Anybody please elaborate these error:-
void main()
{
int a=5, b=60, func();
printf("\nI am in main-1");
int func(){
printf("\nI am in funct");
return 1;
}
func();
printf("\nI am in main-2");
}
The errors I get are:
In function 'main':
Line 8: error: static declaration of 'func' follows non-static
declaration
Line 4: error: previous declaration of 'func' was here
Line 3: warning: return type of 'main' is not 'int'
I think C allows nested class because the following code is working fine:
void outerfunc()
{
int func()
{
printf("\nI am in funct");
return 1;
}
func();
}
void main()
{
printf("\nI am in main-1");
outerfunc();
printf("\nI am in main-2");
}
You are using an extension of the GNU C Compiler which allows the declarations of nested functions. The error comes from the fact, that forward declarations of nested functions under GCC's extension need to be prepended with the auto keyword.
int a=20,b=11;
int main()
{
int a=5, b=60;
auto int func(); // <--------- here
func(); // <- call it
printf("\nI am in main-1");
int func(){
printf("\nI am in funct");
return 1;
}
printf("\nI am in main-2");
return 0;
}
See http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html for more details.
ANSI C doesn't allow nested function definition. And your main function should return int.
Nested functions are not allowed in standard C/C++. Simply (forward) declare the func() inside main() if you want to define it later on.
int main()
{
int a=5, b=60, func();
printf("\nI am in main-1");
int func(); // <---- declare inside main()
printf("\nI am in main-2");
}
int func(){ // <---- define later
printf("\nI am in funct");
return 1;
}
What you are taking about is a GCC specific feature, its never been a "proper" C feature (i.e. part of the ANSI C specification).
If you want to use this feature then I believe what you are after is this:
#include <stdio.h>
int a = 20, b = 11;
int main( int argc, char* argv[] )
{
int a = 5, b = 60;
auto int func( void );
printf("\nI am in main-1");
int func( void )
{
printf("\nI am in funct");
return 1;
}
printf("\nI am in main-2");
return func();
}
The reason why your previous code didn't work is because nested functions have no linkage:
A nested function always has no linkage. Declaring one with extern or static is erroneous. If you need to declare the nested function before its definition, use auto (which is otherwise meaningless for function declarations).
The above sample uses the auto keyword thusly. I've also taken the liberty of fixing your main declaration :-)
Nested functions are a gcc-specific extension; they are not universally supported.
As far as the warning about main, the standard signatures for main are
int main(void)
int main(int argc, char **argv) // or equivalent
An implementation may provide additional signatures (some compilers allow a third parameter for environment variables), but those additional signatures must be documented by the implementation; IOW, void main() is only a valid signature for main if your compiler documentation explicitly lists it as such.
When in doubt, use one of the standard signatures above.
You haven't defined func before calling it.
Relates back to the original line.
You aren't returning int.
It works if you remove the declaration of func() in the int variable declarations.
C++ does not allow functions to be included inside other functions.
Attempting to do so in VS 2010 gives:
'funct' : local function definitions are illegal
You need to move that function and it's declaration outside of main.

Resources