I want to test a new sqrt function to be used instead of the libm one. But both CLion and Netbeans use the libm one instead of mine (there is no need to say them to add -lm in linking).
For instance:
#include stdio.h>
double sqrt(double n) {
printf("Starting\n");
return 1.0;
}
int main () {
printf("Root: %f\n", sqrt(4));
return 0;
}
In Netbeans and CLion, this code does not execute my sqrt (never prints 'Starting' and returns 1.0). Instead, it executes sqrt in libm.a (even though math.h is not included), printing 2.0.
Is there any way to exclude -lm in linking in these IDEs? Do I have to change my function name (it works fine If I do so)?
Alberto
Related
Why does this compile and run this w/o the "-lm" switch on gcc:
#include <stdio.h>
#include <math.h>
int main()
{
printf("2 to the 8th power is %f\n",pow(2.0,8.0));
return(0);
}
but this:
#include <stdio.h>
#include <math.h>
int main()
{
float a,b;
a = 2.0;
b = 8.0;
printf("2 to the 8th power is %f\n",pow(a,b));
return(0);
}
gives the error:
undefined reference to `pow'
unless you link the math library with -lm
The behavior is the same if I use doubles rather than floats. Is there some sort of rudimentary pow() function hidden in standard library, or is the linker just resigned to working with idiots and links the math library for really simple cases?
I'm using gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 if that makes any difference. It's not a big deal, just curious why that happens, thanks!
I had myself, a problem of understanding, what is wrong with the above. I got the same behaviour with gcc -O0. Running executable with strace and gdb showed that no function call made at all.
Scratched my head, read some comments and got it. Me alone, would have guessed the answer for hours. All credits goes to commenters
Try to change your code to
....
double t = (int)(2.0 + 1.0) % 2 + 1.0;
double r = pow(2.0+t,8.0);
....
With -O0 flag you should hopefully get undefined reference to 'pow' message.
I would like to use a library written in D for a C program compilable with MinGW GCC, for Windows. Here are the codes:
dll.d
extern (C) int dsquare(int n) nothrow
{
return n * n;
}
main.c
#include <stdio.h>
int main()
{
int res = dsquare(6); // Expect '36'
printf("res = %d\n", res);
return 0;
}
There is a tutorial on D's site, but it seems to target only Linux. Indeed, no explanation is given for creating such a dynamic D library for Windows and MinGW users.
D's documentation also says that the -shared option should generate a DLL version of the D code, but in my case, it generates an executable, I don't know why.
Also, anything that seems to generate files to be linked targets MVSC formats and nothing seems to be suitable for MinGW GCC compilers.
So, how can I generate a "GCC-friend" DLL with D, so that I can link it to my C program without having to use another compiler, such as GDC or LDC, via gcc main.c -o main -ldll -L. (I guess)?
I attached link with short explanation. Link D onto C is not so straightforward as C to D. Check D.org page here:
https://dlang.org/spec/betterc.html
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.
Anyone knows why this c program compiles and uses the sqrt of math.h?
this would output 2.236068
main.c
#include <stdio.h>
#include "math_utils.h"
int main(void){
printf("%f\n", sqrt(5));
return 0;
}
math_utils.h
#ifndef MATH_UTILS_Hs
#define MATH_UTILS_Hs
double sqrt(double number){
return number + 5;
}
#endif // MATH_UTILS_Hs
I am currently using mingw GCC on windows
gcc performs an optimization where it expects standard library functions to behave like the standard says to turn calls into the C standard library into more efficient machine code. For example, it's likely that gcc emits a single fsqrt instruction for your sqrt() call, never calling your custom sqrt() at all.
You can turn off this behaviour by supplying -fno-builtin to turn this optimization off for all recognized functions or by supplying -fno-builtin-function to turn off this optimization for function only. For example, -fno-builtin-sqrt would make gcc honour your non-standard sqrt().
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 :)