3

Today I have spend considerable time finding a "bug" that can be demonstrated by this simple code:

main.c

#include "func.h"
#include <stdio.h>
void main(){printf("func: %f", getX());}

func.c

#include "func.h"
static float x[2] = {1.0f, 2.0f};
float getX(int n){return x[n];}

func.h

float getX();

and it compiles & links (VS2010 with /W3) without any warning. Sample output from the run is

func: 1.000000

Can someone explain me how it can work if function declaration and definition do not match and why it is not worth to output any warning?

Thanks

Peter Petrik
  • 9,701
  • 5
  • 41
  • 65
  • 1
    `main` must return an `int` in [0,255], not `void`. This is not your main bug, but it is a bug. – John Zwinck Oct 03 '14 at 07:48
  • 1
    [**See this question**](http://stackoverflow.com/questions/51032/is-there-a-difference-between-foovoid-and-foo-in-c-or-c) – WhozCraig Oct 03 '14 at 07:49
  • The key question of how the value of the argument gets set is not answered yet. – R Sahu Oct 03 '14 at 07:51
  • Why is it duplicate? The important part of the question was about passed argument i=0 to the function – Peter Petrik Oct 03 '14 at 07:57
  • Well there are two questions here really: why does this compile without warning/error, and why do I get an output of 1.0? Both questions are duplicates though - the first is a duplicate of the [the linked question](http://stackoverflow.com/questions/5929711/c-function-with-no-parameters-behavior) and the second is a duplicate of various questions such as [this one](http://stackoverflow.com/questions/23833794/consequences-of-calling-a-function-with-fewer-arguments-in-c/23834194#23834194). Don't take it personally though - the question and its answers are still potentially useful. – Paul R Oct 03 '14 at 08:12

2 Answers2

4

This declaration means that getX accepts any number of parameters:

float getX();

To declare a function that takes no parameters, use:

float getX(void);  // This will result in a compiler error for func.c
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
4

In C:

float getX();

is not the same as:

float getX(void);

In the first case you are specifying a function that returns float but takes unspecified parameters - in the second case you are specifying a function which returns float but which takes no parameters.

So a definition of the form float getX(int n) is compatible with the first case, but not the second, which explains why you do not seen an error/warning.

If you change to the correct prototype (the second version) then you should see the required error/warning.

Note that this is different behaviour than for C++, where the two forms are equivalent.

As for the output you are seeing when you run the program, this is just a random consequence of undefined behaviour - literally anything could happen if you call a function with incorrect parameters.

Take home message: in C you should always use the second form when declaring a prototype that takes no parameters - unfortunately you'll find that it's very common for people to omit the void (probably because of bad habits acquired from writing C++ code, or just because it requires fewer keystrokes).

Paul R
  • 208,748
  • 37
  • 389
  • 560