Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the following function definition work?

Tags:

c

#include <stdio.h>
void main() {
    extern int fun(float);
    int a=fun(3.5);
    printf("%d",a);
}

int fun(aa)
float aa;
{
    return ((int)aa);
}

The code block mentioned above compiles fine on my Visual Studio 8 compiler though output is a junk value. But when I compiled the same code on gcc-4.3.4, I got the following compilation error:

prog.c:2: warning: return type of ‘main’ is not ‘int’
prog.c:8: error: conflicting types for ‘fun’
prog.c:3: error: previous declaration of ‘fun’ was here

How will it work when it has following properties:

  1. There is a variable declaration before the beginning of function body.
  2. The function definition does not have the parameter type of the variable.
like image 372
ZoomIn Avatar asked Dec 10 '11 07:12

ZoomIn


1 Answers

The function is written in K&R style, and your prototype for it is incorrect. In fact, there are other problems too...

#include <stdio.h>
void main() {
    extern int fun(float);
    int a=fun(3.5);
    printf("%d",a);
}

int fun(aa)
float aa;
{
    return ((int)aa);
}

The return type of main() is int, at least in Standard C. Your print statement should include a newline.

Your prototype would be OK if the function fun() were written with a prototype:

int fun(float aa) { ... }

However, the function is written in K&R style, and therefore the function expects to be passed a double which it will convert to float:

int fun(double aa_arg) { float aa = aa_arg; ... }

In K&R C, all float values were passed as double. This is why you are getting garbage; you are lying (probably unwittingly) to your compiler, and it is getting its own back by doing GIGO on you.

FWIW: GCC 4.6.1 refuses to compile your code (even without any warning settings). It complains:

f1.c: In function ‘main’:
f1.c:2: warning: return type of ‘main’ is not ‘int’
f1.c: At top level:
f1.c:9: error: conflicting types for ‘fun’
f1.c:3: error: previous declaration of ‘fun’ was here

You can fix this in a number of different ways:

#include <stdio.h>
int main(void)
{
    extern int fun(float);
    int a = fun(3.5);
    printf("%d\n", a);
    return(0);
}

int fun(float aa)
{
    return ((int)aa);
}

Or:

#include <stdio.h>
int main(void)
{
    extern int fun(double);
    int a = fun(3.5);
    printf("%d\n", a);
    return(0);
}

int fun(double aa)
{
    return ((int)aa);
}

Or:

#include <stdio.h>
int main(void)
{
    extern int fun(double);
    int a = fun(3.5);
    printf("%d\n", a);
    return(0);
}

int fun(aa)
double aa;
{
    return ((int)aa);
}

Or:

#include <stdio.h>
int main(void)
{
    extern int fun(double);
    int a = fun(3.5);
    printf("%d\n", a);
    return(0);
}

int fun(aa)
float aa;
{
    return ((int)aa);
}

Or:

#include <stdio.h>
int main(void)
{
    extern int fun();
    int a = fun(3.5);
    printf("%d\n", a);
    return(0);
}

int fun(aa)
float aa;
{
    return ((int)aa);
}

I believe these are all correct and they all should compile without warnings (unless you ask the compiler to complain about old style (K&R) function definitions, etc).

With GCC set to rather fussy, I get the warnings:

/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f2.c -o f2  
f2.c:12: warning: no previous prototype for ‘fun’
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f3.c -o f3  
f3.c:12: warning: no previous prototype for ‘fun’
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f4.c -o f4  
f4.c:12: warning: function declaration isn’t a prototype
f4.c: In function ‘fun’:
f4.c:13: warning: old-style function definition
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f5.c -o f5  
f5.c:12: warning: function declaration isn’t a prototype
f5.c: In function ‘fun’:
f5.c:13: warning: old-style function definition
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f6.c -o f6  
f6.c: In function ‘main’:
f6.c:5: warning: function declaration isn’t a prototype
f6.c: At top level:
f6.c:12: warning: function declaration isn’t a prototype
f6.c: In function ‘fun’:
f6.c:13: warning: old-style function definition
like image 74
Jonathan Leffler Avatar answered Oct 22 '22 21:10

Jonathan Leffler