7

I'm trying to test some of the functions in fenv.h, however, when I compile the below function ld fails with undefined reference to 'feclearexcept' and undefined reference to 'fetestexcept'. I'm running hardened gentoo compiled against uclibc, and I suspect that this is at least somewhat related

#include <stdio.h>      /* printf */
#include <math.h>       /* sqrt */
#include <fenv.h>      
#pragma STDC FENV_ACCESS on

int main ()
{
  feclearexcept (FE_ALL_EXCEPT);
  sqrt(-1);
  if (fetestexcept(FE_INVALID)) printf ("sqrt(-1) raises FE_INVALID\n");
  return 0;
}

fenv.h is in /usr/include. There are static and dynamic libraries (libm.a, libm.so) in /usr/lib. I am compiling with gcc -o test test.c -lm; does anyone have any ideas why the linker can't find the relevant functions. It seems like nothing in fenv.h has a corresponding library.

UPDATE: this decade old blog post seems to suggest that fenv is not supported by uclibc. I cannot determine if this is the case still, but if it were is there anything to be done. http://uclibc.10924.n7.nabble.com/missing-fenv-h-for-qemu-td2703.html

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
ragingSloth
  • 1,094
  • 8
  • 22
  • Can the linker find `sqrt()`? – user12205 Oct 17 '15 at 21:24
  • I ran the exact posted code. ubuntu linux 14.04 and gcc. the compiler raised the following: warning: ignoring #pragma STDC FENV_ACCESS. but it did not have any problems finding the feclearexcept() function nor the values FE_ALL_EXCEPT and FE_INVALID. Is the fenv.h file in your /usr/include directory, as it should be? – user3629249 Oct 17 '15 at 21:44
  • it is. I run hardened uclibc gentoo linux, so I suspect an idiosyncracy thereof is the problem. The code it definitely valid, and will compile on most systems. – ragingSloth Oct 17 '15 at 22:04

2 Answers2

8

Libraries go last, try compiling with

$ gcc -o test test.c -lm

I tried your exact program on my x86_64 Linux system with the above compilation statement, it built and ran just fine:

$ gcc -o fenv fenv.c -lm
$ ./fenv
sqrt(-1) raises FE_INVALID

My resulting binary had the following dependencies:

$ ldd ./fenv
    linux-vdso.so.1 =>  (0x00007ffd924b7000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fca457e8000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca4541e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fca45af0000)

I also verified that the functions from fenv.h really do live in the math library:

emil@synapse:~/data/src$ strings /lib/x86_64-linux-gnu/libm.so.6 | grep -E ^fe
feclearexcept
fegetexceptflag
feraiseexcept
fesetexceptflag
fetestexcept
fegetround
fesetround
fegetenv
feholdexcept
fesetenv
feupdateenv
fedisableexcept
feenableexcept
fegetexcept

So perhaps there's something else wrong in your setup.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • could you unmark this as a duplicate? sqrt is defined properly with both placements of -lm. The problem seems to be restricted to functions in fenv.h , and I really could use an answer. – ragingSloth Oct 17 '15 at 21:18
  • @ragingSloth That `sqrt` applied to a constant doe snot cause a problem is not proof that the math library is correctly linked in. There is a `sqrt` assembly instruction, and you are applying it to a constant anyway. – Pascal Cuoq Oct 17 '15 at 21:24
  • yeah, I'm using uclibc instead of gnu libc, so I think that's a part of the issue. Interestingly, both static and dynamic versions of libm do not list any of the relevant functions. – ragingSloth Oct 17 '15 at 22:05
0

Recent uclib-ng documents the lack of support for fenv.h at: https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/docs/uClibc_vs_SuSv3.txt?h=v1.0.29#n104

Unimplemented mathematical interfaces:
--------------------------------------
math.h: [126] many
complex.h: [46] all, except cabs
fenv.h: [11] all
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985