Codeblocks compile different my program than gcc in comand - c

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.

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).

Related

undefined reference to sin and exp in c [duplicate]

Well, I think my problem is a little bit interesting and I want to understand what's happening on my Ubuntu box.
I compiled and linked the following useless piece of code with gcc -lm -o useless useless.c:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100)));
return(0);
}
So far so good. But when I change to this:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int freq = 440;
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100)));
return(0);
}
And I try to compile using the same command line, and gcc responds:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
And it stops. What is happening? Why can't I compile that way?
I also tried a sudo ldconfig -v without success.
There are two different things going on here.
For the first example, the compiler doesn't generate a call to sin. It sees that the argument is a constant expression, so it replaces the sin(...) call with the result of the expression, and the math library isn't needed. It will work just as well without the -lm. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)
(If you compile with
gcc -S useless.c
and take a look at useless.s, the generated assembly language listing, you can see that there's no call to sin.)
For the second example, you do need the -lm option -- but it needs to be at the end of the command line, or at least after the file (useless.c) that needs it:
gcc -o useless useless.c -lm
or
gcc useless.c -lm -o useless
The linker processes files in order, keeping track of unresolved symbols for each one (sin, referred to by useless.o), and then resolving them as it sees their definitions. If you put the -lm first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin in useless.o, it's too late.

No parameter checking in GCC

I have written a C program, which consists below given three files in same directory
main.c
#include<stdio.h>
#include "test.h"
int main()
{
int b=0;
b = test_add(3,2);
printf("Added: b=%d\n\n",b);
return 0;
}
test.h
int test_add(int a, int b);
test.c
int test_add(int a, int b, int c)
{
return a+b+c;
}
I am compiling the program using below command:
$gcc -Wall -Wextra main.c test.c
It compiles successfully. I can see there is mismatch in number of arguments of calling function and its actual definition. Compiler doesn't give any warning/error for such problem. How can this type of errors be reported by compiler?
This shows one of the oddities of the C standard. It allows entities such as functions to be undefined.
The actual error is that you did not
#include "test.h"
in you test.c file.
That means that the main file only sees the version of the function with three parameters. When it reaches the function call, it implicitly declares the function with two parameters.
When you run it, you get bogus values for b. I am guessing the superuser's password could somehow be in there ;)
If you add the include directive, you get an error at compile time.
What worries me, that there is no warning, not even with -Wall -Wextra -pedantic.

linker reports undefined reference but code compiles OK [duplicate]

This question already has answers here:
gcc will not properly include math.h
(2 answers)
Closed 8 years ago.
I'm trying to learn enough c to satisfy my occasional need to write simple programs that answer specific questions I have. I've been following a tutorial and using Geany for ease of use. Instead, I can't seem to get the simplest program to run. Here is my source code:
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
int x, y;
double c, sqr_c;
for (x = 10; x <= 31; x++)
{
for (y = 10; y <= 31; y++)
{
c = 1000 * x * x + y * y;
sqr_c = sqrt(c);
printf ("%f\n", sqr_c);
}
}
return 0;
}
It compiles fine (gcc -c) but when I try to build an executable, I get:
gcc "concsqr.c" -Wall -o "concsqr" (in directory: /home/chip)
/tmp/cccSmdZS.o: In function `main':
concsqr.c:(.text+0x4b): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Compilation failed.
I read something about making sure the linker can locate the library where sqrt() is defined, but I do not know how to do that, and wouldn't it be in a standard location anyway? Why doesn't the linker already know where it is? It's a standard library for c.
You must try to compile your program with the -lm flag as libm.so is the math library, and the -l flag adds a lib prefix and .a or .so suffix.
gcc concsqr.c -Wall -o concsqr -lm

Why does this code keep giving this error? Syntax error: Bad for loop variable

This is copied from The C Programming Language By Ritchie. I've tried to make some modifications but it always gets stuck on the for loop (line 7)
#include <stdio.h>
main()
{
int fahr;
for(fahr = 0; fahr <= 300; fahr = fahr + 20)
{
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
}
error: ./farn.c: 8: ./farn.c: Syntax error: Bad for loop variable
I reproduced your problem. On Ubuntu, /bin/sh is symbolically linked to dash.
$ dash ./farn.c
./farn.c: 8: Syntax error: Bad for loop variable
It is very rare for a C program to be correctly interpreted by a Bourne shell interpreter (or one of its derivatives).
Compile the program with a C compiler, and run the executable (alternatively, use a C language interpreter if you can find one). On Ubuntu, you can use gcc:
$ gcc -W -Wall -Werror -pedantic -std=c99 farn.c -o farn
$ ./farn
Since the K&R book predates C.99, the above compilation command will generate an error:
cc1: warnings being treated as errors
farn.c:4: warning: return type defaults to 'int'
To fix this, you can simply update the declaration of main() with an explicit int return type. In C.99, encountering the } at the end of main() implicitly returns 0, so adding int is sufficient.
#include <stdio.h>
int main()
{
int fahr;
for(fahr = 0; fahr <= 300; fahr = fahr + 20)
{
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
}
Other than the fact that you're defining main() in a very lazy way and the lack of a return statement, I don't see anything wrong at all with the code above. After fixing those 2 issues, it compiled and ran just fine with the following options:
gcc temperature.c -g -Wall -Werror -pedantic -o temperature
As an aside, the entry-point to main should be either of:
int main(void) // You *can* leave void out here, but it's best to be explicit
int main(int argc, char* argv[]) // 2nd arg could also be char** argv
And you should always return an integer value from main, usually a return of 0 indicates the program ran successfully.
Your code compiles correctly. This is the proof : http://codepad.org/hryZ2dEm
I have also added the return type and the return instruction in the main function to make your code conform to the standard. Try to use the small changes I have inserted.
Let me know if you still have a problem.
Thank for the advice everyone. I solved my problem by using GCC like a boss.
gcc farn.c -o farn
then
./farn
works great. :-)

C programming - "Undefined symbol referenced in file"

I am trying to write a program to approximate pi. It basically takes random points between 0.00 and 1.00 and compares them to the bound of a circle, and the ratio of points inside the circle to total points should approach pi (A very quick explanation, the specification goes in depth much more).
However, I am getting the following error when compiling with gcc:
Undefined first referenced
symbol in file
pow /var/tmp//cc6gSbfE.o
ld: fatal: symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status
What is happening with this? I've never seen this error before, and I don't know why it's coming up. Here is my code (though I haven't fully tested it since I can't get past the error):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void) {
float x, y;
float coordSquared;
float coordRoot;
float ratio;
int n;
int count;
int i;
printf("Enter number of points: ");
scanf("%d", &n);
srand(time(0));
for (i = 0; i < n; i++) {
x = rand();
y = rand();
coordSquared = pow(x, 2) + pow(y, 2);
coordRoot = pow(coordSquared, 0.5);
if ((x < coordRoot) && (y < coordRoot)) {
count++;
}
}
ratio = count / n;
ratio = ratio * 4;
printf("Pi is approximately %f", ratio);
return 0;
}
use -lm during compilation(or linking) to include math library.
Like this: gcc yourFile.c -o yourfile -lm
need to Link with -lm.
gcc test.c -o test -lm
The error is produced by the linker, ld. It is telling you that the symbol pow cannot be found (is undefined in all the object files handled by the linker). The solution is to include the library which includes the implementation of the pow() function, libm (m for math). [1] Add the -lm switch to your compiler command line invocation (after all the source file specifications) to do so, e.g.
gcc -o a.out source.c -lm
[1] Alternatively, you could have your own implementation of pow() in a separate translation unit or a library, but you would still have to tell the compiler/linker where to find it.

Resources