3

I was trying today to check an Answer and I realized that if i use codeblocks (with gcc) i have to treat the error different from the command line (Ubuntu Linux) using gcc.

The program is like this:

#include<stdio.h>
#include<math.h>

int main(void){
    double len,x,y =0;
    int n=123456;

    len=floor(log10(abs(n))) + 1;

    x = n / pow(10, len / 2);
    y = n - x * pow(10, len / 2);

    printf("First Half = %f",x);
    printf("\nSecond Half = %f",y);

    return 0;
}

And if i try to compile it i get:

error: implicit declaration of function ‘abs’ [-Werror=implicit-function-declaration]|

So here is the funny thing. I added -lm to the Compiler => global compiler => settings => Other settings, but the result is the same.

It is working only if i include stdlib.h.

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main(void){
    double len,x,y =0;
    int n=123456;

    len=floor(log10(abs(n))) + 1;

    x = n / pow(10, len / 2);
    y = n - x * pow(10, len / 2);

    printf("First Half = %f",x);
    printf("\nSecond Half = %f",y);

    return 0;
}

But if I use command line (in terminal) using the comand:

   gcc program.c -o program -lm

The program compiled successfully.

My question: Why happens this ? I did a research on interent and found that some people says the abs function is declared in stdlib.h, not math.h. but if i compile in command line (without including stdlib.h) with -lm works. I'm confused.

14
  • Look at the command line in CodeBlocks that it does for each file. It shows this in the build log. Compare that to the command line you are using outside codeblocks. Commented Aug 14, 2015 at 22:31
  • @B. Nadolson please explain... Commented Aug 14, 2015 at 22:32
  • At the bottom window, there is a series of tabs like "Search Results", "Build log", "Build messages" .... each source file it says something like gcc -Winline -W -fexceptions -g -lld -D_DEBUG myfile.c -o myfile.o as it compiles each file. Commented Aug 14, 2015 at 22:35
  • 2
    AGAIN JUST FOR YOU ... a header is not a library. abs() is declared in stdlib.h, and with the GNU C library, the actual code happens to be found in libm.so. Commented Aug 14, 2015 at 23:03
  • 1
    Ok, finally enough repetition :) Then just adding a bit of advise: Linux and GNU are not all in the world and you'll have to be careful in general where to find declarations and implementations of functions, e.g., on both Linux and FreeBSD, dlopen() is declared in dlfcn.h, but the implementation is found in libc (automatically linked) for FreeBSD and in libdl (needing explicit -ldl) for Linux. Commented Aug 14, 2015 at 23:10

1 Answer 1

5

Short answer: Try

gcc -Wall -Wextra -pedantic -o program -lm

or

gcc -Wall -Wextra -Werror -pedantic -o program -lm

to make it fail on warnings as Codeblocks seems to do.

Long answer: Linking to a library is a completely different matter than including a header file. In C, for historic reasons, it is "allowed" to use a function that is not declared. The compiler in this case assumes a function returning int and taking whatever arguments you give it. For abs(), these assumptions hold. So later, the linker finds the function when linking with libm and everything is fine.

But there are quite some catches: First you will miss simple typos if you don't enable warnings. Second, the compiler is unable to check the arguments you give -> crashing program ahead. And even more problems are to expect if the function does return something other than int.

abs() is declared in stdlib.h. To use it, include this header. And always enable compiler warnings (Codeblocks obviously does it for you).

Sign up to request clarification or add additional context in comments.

6 Comments

i compile (both codeblocks and from command line) allways with this "-Wall -Wextra -Werror -Wstrict-prototypes -Wconversion --std=c11 -Og". You say that abs is declared in stdlib.h, why i can compile the program in command line using -lm without including stdlib.h?
This contradicts your question: "if I use command line (in terminal) using the comand: gcc program.c -o program -lm The program compiled successfully." -- I don't see any warning flags here. Why this code is acceptable is explained in my answer. There was a time when C didn't even have prototypes, so it was reasonable that declarations of functions could be omitted.
probably i was not clear, codeblocks will not compile without including stdlib.h but in command line (without stdlib.h) by adding -lm it will. If you use CodeBlocks, please try the first code and explain that.
probably you didn't read my answer carefully? Or is it just about -Werror? this turns all warnings into errors, so compilation stops. And again .. -lm has nothing to do with it, that's for linking the library (after the compiler did its work). Without it, you'd get an "unresolved symbol" error from the linker.
Sir are you using GCC ? It is possible that this happens because i use Linux and you probably not? you are not helping me at all. If i don't include -lm in command line it will not compile my program with or without stdlib.h. Hope i made my self clear. "gcc program.c -o program /tmp/ccxOJHWB.o: In function main': program.c:(.text+0x2c): undefined reference to log10' program.c:(.text+0x31): undefined reference to floor' program.c:(.text+0x85): undefined reference to pow' program.c:(.text+0xd2): undefined reference to `pow' collect2: error: ld returned 1 exit status "
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.