2

The Problem

I'm writing the following code, which, as excerpted below, should return the total amount of money depending on the number of each type of coin.

static int qNum = 0;
static int dNum = 0;
static int nNum = 0;
static int pNum = 0;

int main(){
    float totalCost;
    totalCost = totalMoneyCalc();
}
float totalMoneyCalc(void){
    float total;
    total = qNum*.25 + dNum*.10 + nNum*.05 + pNum*.01;
    return total;
}

The Errors I'm Getting

note: previous implicit declaration of ‘totalMoneyCalc’ was here
     totalCost = totalMoneyCalc();
error: conflicting types for ‘totalMoneyCalc’
 float totalMoneyCalc(){

However, when I remove the "float" part of the totalMoneyCalc() function, it doesn't return any more errors. Aren't you supposed to assign functions types?

What I've Tried

I looked at this question on SO, which says something about having to pass in void as a param for functions that don't take in anything but adding that to the original code didn't work either. I also checked out some primers on using floats for functions in C, but I followed those and it's still not working. Am I supposed to be doing something with pointers? I don't understand why returning a value in a function to be assigned to a variable is different from ints to floats. If anyone has suggestions, fixes, or explanations, I'd really appreciate it.

Community
  • 1
  • 1
sc1892353
  • 85
  • 1
  • 10
  • 4
    You need a prototype if you're calling a func that's defined later in the code. – MightyPork Jan 19 '15 at 22:01
  • 1
    There are numerous questions on SO about money which use `float` for dollars, pounds or euros, but should use `int` for cents or pennies, please do some research. – Weather Vane Jan 19 '15 at 22:03
  • @WeatherVane: Is the upside to using int because of the number of bytes float takes up? – sc1892353 Jan 19 '15 at 22:07
  • 2
    You should have received a warning telling you implicit declaration of `totalMoneyCalc` returns `int`. if you don't, crank up your warnings higher. – WhozCraig Jan 19 '15 at 22:08
  • 1
    *"Is the upside to using int because of the number of bytes float takes up?"* No, it is because `float` lacks precision, especially when testing for equality. On my platform `float` and `int` both take 4 bytes. – Weather Vane Jan 19 '15 at 22:08
  • No, but because you cannot represent all decimal digits in any languages' floating point types (because of the binary representation) – Philipp Murry Jan 19 '15 at 22:09
  • Gotcha, thanks for the suggestions regarding float vs. int! – sc1892353 Jan 19 '15 at 22:19

2 Answers2

10

Yes, all C functions have types. Prior to the 1999 standard, it was legal to omit the return type from a declaration; that would implicitly give it a return type of int. As of C99, the return type must always be specified explicitly.

Also prior to C99, it was legal to call a function with no visible declaration. The compiler would assume a function with a return type of int (that's the "previous implicit declaration" referred to in the error message). C99 dropped that rule; now all functions must be visibly declared before you can call them.

Assuming you're using gcc (that looks like a gcc error message), the compiler enforces the C90 rules by default. The problem it's reporting is that the implicit declaration of totalMoneyCalc (as a function returning int) conflicts with the later explicit declaration as a function returning float.

The solution is to declare totalMoneyCalc before the call. You can either add a separate "forward" declaration before main:

float totalMoneyCalc(void);

or you can move the entire definition above main. (This is a good idea even in C90.)

A minor point: int main() should be int main(void).

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • It's not widely known that such "forward" declaration could occur even inside of `main` function, just like normal declaration of variable. It's not recommended practice. Specifically `float total, totalMoneyCalc(void);` is allowed (it declares variable and function), but confusing and should be avoided. – Grzegorz Szpetkowski Jan 19 '15 at 22:27
2

The compiler needs to know about the function before you use it. If the function is unknown to the compiler then it will not be able to know whether the function returns double or float or if it's first parameter is a pointer or a struct, so it will by default think of them all as int's.

You can to add a function prototype before main()

float totalMoneyCalc(void);

or move the entire function definition before main().

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97