Compile error using sqrt() in c - c

I have a problem using sqrt() in c.
I'm trying to do something like this:
int a;
a = sqrt(9);
etc
I'm restricted to use:
gcc -ansi -Wall -pedantic oneFile.c anotherFile.c thirdFile.c -o outputFileName
How can I make this compile without using the -lm command?
Yes, I have #include !
Is there any way around this and still use sqrt()?
Thanks

You can't make it compile without -lm. That's an instruction to the linker to compile against the built-in math library. It isn't enough to say #include <math.h>, because that's only a header file - there's no code in there, that simply tells the compiler what the functions you're using look like. You still need to actually get the implementation of that function into your code, and -lm basically tells the linker look in libm, check to see if it has any functions that we haven't found yet. If you don't look in there, you'll never be able to actually execute sqrt because the code simply isn't in your program.
If you're working on a homework assignment and are restricted to using that command line, then it's possible that part of your assignment is to not use anything from the math library, and so you may be expected to consider an alternate approach.

just try with this function, If you don`t want to use library.
Sq_root(n)
{
count=0;
int i = 0;
for(i=1;sum<=n;i+=2)
{
sum+=i;
count++;
}
return (count);
}
This will work, without any math library.

use #include <math.h> in header
else use user define function

int int_sqrt(int x){
int s, t;
s = 1; t = x;
while (s < t) {
s <<= 1;
t >>= 1;
}
do {
t = s;
s = (x / s + s) >> 1;
} while (s < t);
return t;
}

Related

Why is no warning given for the wrong use of __attribute__((pure)) in GCC?

I am trying to understand pure functions, and have been reading through the Wikipedia article on that topic. I wrote the minimal sample program as follows:
#include <stdio.h>
static int a = 1;
static __attribute__((pure)) int pure_function(int x, int y)
{
return x + y;
}
static __attribute__((pure)) int impure_function(int x, int y)
{
a++;
return x + y;
}
int main(void)
{
printf("pure_function(0, 0) = %d\n", pure_function(0, 0));
printf("impure_function(0, 0) = %d\n", impure_function(0, 0));
return 0;
}
I compiled this program with gcc -O2 -Wall -Wextra, expecting that an error, or at least a warning, should have been issued for decorating impure_function() with __attribute__((pure)). However, I received no warnings or errors, and the program also ran without issues.
Isn't marking impure_function() with __attribute__((pure)) incorrect? If so, why does it compile without any errors or warnings, even with the -Wextra and -Wall flags?
Thanks in advance!
Doing this is incorrect and you are responsible for using the attribute correctly.
Look at this example:
static __attribute__((pure)) int impure_function(int x, int y)
{
extern int a;
a++;
return x + y;
}
void caller()
{
impure_function(1, 1);
}
Code generated by GCC (with -O1) for the function caller is:
caller():
ret
As you can see, the impure_function call was completely removed because compiler treats it as "pure".
GCC can mark the function as "pure" internally automatically if it sees its definition:
static __attribute__((noinline)) int pure_function(int x, int y)
{
return x + y;
}
void caller()
{
pure_function(1, 1);
}
Generated code:
caller():
ret
So there is no point in using this attribute on functions that are visible to the compiler. It is supposed to be used when definition is not available, for example when function is defined in another DLL. That means that when it is used in a proper place the compiler won't be able to perform a sanity check anyway. Implementing a warning thus is not very useful (although not meaningless).
I don't think there is anything stopping GCC developers from implementing such warning, except time that must be spend.
A pure function is a hint for the optimizing compiler. Probably, gcc don't care about pure functions when you pass just -O0 to it (the default optimizations). So if f is pure (and defined outside of your translation unit, e.g. in some outside library), the GCC compiler might optimize y = f(x) + f(x); into something like
{
int tmp = f(x); /// tmp is a fresh variable, not appearing elsewhere
y = tmp + tmp;
}
but if f is not pure (which is the usual case: think of f calling printf or malloc), such an optimization is forbidden.
Standard math functions like sin or sqrt are pure (except for IEEE rounding mode craziness, see http://floating-point-gui.de/ and Fluctuat for more), and they are complex enough to compute to make such optimizations worthwhile.
You might compile your code with gcc -O2 -Wall -fdump-tree-all to guess what is happening inside the compiler. You could add the -fverbose-asm -S flags to get a generated *.s assembler file.
You could also read the Bismon draft report (notably its section §1.4). It might give some intuitions related to your question.
In your particular case, I am guessing that gcc is inlining your calls; and then purity matters less.
If you have time to spend, you might consider writing your own GCC plugin to make such a warning. You'll spend months in writing it! These old slides might still be useful to you, even if the details are obsolete.
At the theoretical level, be aware of Rice's theorem. A consequence of it is that perfect optimization of pure functions is probably impossible.
Be aware of the GCC Resource Center, located in Bombay.

Linking .c and .h files

For my program I am linking 3 files in total. A main.c, sortfile.c and my.h(header file). For my sortfile.c I am implementing a OddEven Sort. I am unsure whether my coding algorithm is correct. Also would like to know what information usually goes in a header file. Is it only the other two c files vide #include?
#include <stdio.h>
void swap(int *, int *);
void Odd_Even_Sort(int *);
/* swaps the elements */
void swap(int * x, int * y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
/* sorts the array using oddeven algorithm */
void Odd_Even_Sort(int * x)
{
int sort = 0, i;
while (!sort)
{
sort = 1;
for (i = 1;i < MAX;i += 2)
{
if (x[i] > x[i+1])
{
swap(&x[i], &x[i+1]);
sort = 0;
}
}
for (i = 0;i < MAX - 1;i += 2)
{
if (x[i] > x[i + 1])
{
swap(&x[i], &x[i + 1]);
sort = 0;
}
}
}
I did not include a main in the sortfile.c because I intended to put main in the main.c file.
You look confused. Read first the wikipage on linkers and on compilers. You don't link source files, but only object files and libraries.
(I am guessing and supposing and hoping for you that you are using Linux)
You also compile translation units into object files.
Header files are for the preprocessor (the first "phase" of the compilation). The preprocessing is a textual operation. See this answer for some hint.
So you probably want to compile your main.c into main.o with
gcc -Wall -g -c main.c -o main.o
(the -Wall asks for all warnings, so never forget that; the -g asks for debugging information; -c asks to compile some source into some object file; order of program arguments to gcc matters a big lot).
Likewise, you want to compile your sortfile.c into sortfile.o. I leave as an exercise to get the right command doing that.
Finally, you want to get an executable program myprogsort, by linking both object files. Do that with
gcc -g main.o sortfile.o -o myprogsort
But you really want to use some build automation tool. Learn about GNU make. Write your Makefile (beware, tabs are important in it). See this example. Don't forget to try make -p to understand (and take advantage of) all the builtin rules make is knowing.
Also would like to know what information usually goes in a header file.
Conventionally you want only declarations in your common header file (which you would #include in every source file composing a translation unit). You can also add definitions of static inline functions. Read more about inline functions (you probably don't need them at first).
Don't forget to learn how to use the gdb debugger. You probably will run
gdb ./myprogsort
more than once. Don't forget to rebuild your thing after changes to source code.
Look also inside the source code of some medium sized free software project coded in C on github. You'll learn a big lot.

Codeblocks compile different my program than gcc in comand

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

Passing variables to fmax

So I have the following code:
#include <math.h>
int main (void) {
float max = fmax (1.0,2.0);
return 0;
}
Which compiles and runs fine, but if instead of passing 1.0 and 2.0 to the function I pass a, b with those values:
#include <math.h>
int main (void) {
float a = 1.0; float b = 2.0;
float max = fmax (a,b);
return 0;
}
I get the following error:
undefined reference to `fmax'
What is the diffrence? What I'm doing wrong?
I'm using this command to compile:
c99 fmax_test.c
In the first case fmax probably gets optimised away at compile time. In the second case it does not and you then get a link error. Without knowing what compiler you are using it's hard to give a specific remedy, but if it's gcc then you may need to add -lm, e.g.
c99 -Wall fmax_test.c -lm
Note also that fmax is for doubles - you should be using fmaxf for floats.
compile with -lm
i'm using gcc. maybe not OK with your compiler.
try this:
c99 fmax_test.c -lm

C fabs returning integer

I have a strange problem with fabs function in C code. I have two double values and I want to find the absolute value of their difference using code like this:
a = 87.967498;
b = 218.025015;
if (fabs(a-b)<2.0)
...code to execute
The value of fabs(a-b) is an int and is equal to 1. I don't know whats the problem here and I can't find anything on the net. Any help would be great!!
You didn't include <math.h>. Add the following line to your other includes:
#include <math.h>
In order to find such errors easier I recommend you to use verbose compiler warnings (gcc -Wall -Wextra ... if you use gcc).
The only way that fabs could return an int is either:
Your program uses a declaration of fabs other than the version declared in math.h.
Your program failed to include math.h and so does not declare fabs at all. In which case parameters and return values default to int. Which is of course an error because the actual implementation of fabs does not match and so the value returned is nonsense.
See this code:
#include <math.h>
#include <stdio.h>
int main()
{
float a = 87.967498;
float b = 218.025015;
float diff = a-b;
printf("diff=%f\nfabs(diff)=%f\n",diff,fabs(diff));
if (fabs(diff)<2.0) {
printf("OK\n");
} else {
printf("FAIL\n");
}
return 0;
}
It produces this output:
diego#malti:~/tmp$ clang test-math.c -o test-math -lm
diego#malti:~/tmp$ ./test-math
diff=-130.057510
fabs(diff)=130.057510
FAIL
See? The application is OK, the diff (218-87=130), which is not smaller then 2.
See also then when I am compile, I also link -lm to get the mathematical library. The same syntax applies for gcc, I just love using clang :)

Resources