1

When compiling a C program in Visual Studio 2013 the following may produce different results:

#include <math.h>

void bar(void) {
    double f = fabs(-1.0);
    /* f is 1.0 */
}

and

void foo(void) {
    double f = fabs(-1.0);
    /* f is 0 */
}

and the same snippet without including math.h. When omitting the include, the compiler does not report an error and assumes fabs has the following signature int fabs().

Is there anyway to force the compiler to report this as an error or even a warning?

phuclv
  • 37,963
  • 15
  • 156
  • 475
bennypk
  • 11
  • 2

1 Answers1

0

In older C standards if a function is used before it's declared then it's assumed to receive an unknown number of arguments (under default promotion like in variadic functions such as printf) and return int. The compiler will expect the symbol to be fixed later during linking stage so no errors should be reported

So without including math.h the compiler doesn't know the prototype of fabs and will assume that it accepts any kinds of parameters and returns int. Then when linking the linker really found a symbol with the expected name and resolves to that function, but due to the mismatch in the function signature the behavior is undefined. Turn on all warnings and you'll see something about implicit return type

In VS2013 I got the below warning even without increasing the warning level

Warning 1   warning C4013: 'fabs' undefined; assuming extern returning int

For more information read

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • I compiled the code with the maximum warning level in Visual Studio 2013, but couldn't find any relevant warning or error – bennypk Jan 22 '15 at 16:43
  • it may depend on compiler. Using gcc in strict c99 mode emits `warning: implicit declaration of function 'fabs' [-Wimplicit-function -declaration]` and `warning: incompatible implicit declaration of built-in function 'fab s' [enabled by default]` warning – phuclv Jan 22 '15 at 16:56
  • @bennypk VS is a C++ compiler so you need to compile in C mode by using `.c` file extension, that'll give you the warning. In C++ that won't even compile because there's no implicit int return in C++ – phuclv Jan 22 '15 at 17:01
  • read more [warning: implicit declaration of function](http://stackoverflow.com/questions/8440816/warning-implicit-declaration-of-function) [C function calls: Understanding the “implicit int” rule](http://stackoverflow.com/questions/8220463/c-function-calls-understanding-the-implicit-int-rule) [What does “implicit declaration of function” mean?](http://stackoverflow.com/questions/2161304/what-does-implicit-declaration-of-function-mean) – phuclv Jan 22 '15 at 17:04
  • Let me emphasize that the code is compiled as C with VS. When the same codebase is compiled with gcc, gcc gladly emits a warning. The question again, is how to make VS report a warning or error. – bennypk Jan 23 '15 at 17:54
  • as I said, when compiling in VS as a `.c` file it automatically emits a warning – phuclv Jan 23 '15 at 18:19
  • 1
    You need warning level `/W3` or higher. With `/W3` I see: ` warning C4013: 'fabs' undefined; assuming extern returning int` – njuffa Jan 24 '15 at 17:55
  • @njuffa yes the default warning level is `/W3` so you don't need to change it unless you've lowered it before – phuclv Jan 24 '15 at 18:34
  • 1
    @LưuVĩnhPhúc Complete agreement. I should have directed my comment directly at the asker, as I was responding to his most recent comment. – njuffa Jan 24 '15 at 18:40
  • 1
    I checked again and the warning (now treated as an error) appears. Not sure why it didn't appear before. I must have somehow missed it. Thanks again – bennypk Jan 25 '15 at 10:56
  • to some one who downvoted this: what's wrong in this answer, is it too hard to type a comment? – phuclv Jan 29 '15 at 04:02