7

I have an example code:

#include <quadmath.h>

int main()
{
    __float128 foo=123;
    cosq(foo);
    return 0;
}

I tried to compile it with the following commands:

g++ f128.cpp -lquadmath
g++ f128.cpp /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a
g++ f128.cpp /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a /usr/lib64/libquadmath.so.0
g++ f128.cpp /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a /usr/lib64/libquadmath.so.0 /usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a

All these commands produce one and the same error:

f128.cpp:(.text+0x1b): undefined reference to `cosq(__float128)'

I also tried to declare cosq as follows, without inluding quadmath.h. Declarations of such style are used in C++ interface to fortran subroutines in other programs, and they work well.

extern "C" __float128 cosq_(__float128 *op);
extern "C" __float128 cosq_(__float128 op);
extern "C" __float128 cosq(__float128 *op);
...and so on...

Result was the same.

Then I tried to use cosq in Fortran:

PROGRAM test

        REAL*16 foo
        REAL*16 res

        foo=1;
        res=cos(foo)
        PRINT *,res
END

This program compiles and executes well (prints the answer with lots of digits), so cosq works in it. This program was compiled with no options: gfortran f128.f90.

OS is OpenSUSE 12.1, gcc version is 4.6.2. *.h, *.a and *.so files mentioned are provided by gcc46-fortran and libquadmath46 packages.

What is the proper way to use cosq and other quadmath functions in C++? I wouldn't like to write Fortran wrappers for them.

Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
Sergey
  • 7,985
  • 4
  • 48
  • 80
  • Are you sure /usr/lib64/libquadmath.so.0 exists? What's the output of: `file /usr/lib64/libquadmath.*` – Nikos C. Dec 08 '12 at 18:10
  • All files exist. If it didn't exist, linker would print an error about nonexistance. `/usr/lib64/libquadmath.so.0` is the symlink to `/usr/lib64/libquadmath.so.0.0.0`, which is the actual library. `/usr/lib64/gcc/x86_64-suse-linux/4.6/libquadmath.a` exits too. Linking with `-lquadmath` produces the error shown above, but not a missing library error. – Sergey Dec 08 '12 at 18:13
  • Does it work when you use `cosq_(foo);`? – Nikos C. Dec 08 '12 at 18:22
  • @Nikos - No, it does not. Moreover, it does not work when I use `cosq_(&foo)` and appropriate extern declaration, which would be more correct for functions written in Fortran. – Sergey Dec 08 '12 at 18:24
  • I suppose it also doesn't work for plain C, right? This looks like a bug to me. Unless you're supposed to install some additional package from your suse repo. – Nikos C. Dec 08 '12 at 18:26
  • @Nikos - Do you mean the same program compiled with `gcc`, but not `g++` under plain C? Yes, it doesn't work. There is nothing more about quadmath in my repos, so I'll try to search some additional repos and compile the library from gcc sources, maybe it will help. Anyway, thank you for your help effort. – Sergey Dec 08 '12 at 18:33
  • Try to install a more recent version of openSUSE (perhaps in VirtualBox). I strongly suspect this is a bug that might have been fixed. Or, alternatively, try to find a repo that offers you GCC 4.7.2 for openSUSE 12.1. – Nikos C. Dec 08 '12 at 18:36

1 Answers1

6

First, according to Nikos C. advise, I boot up OpenSUSE 12.2 liveCD (which has gcc 4.7.1) on another machine, but got the same error.

Then I posted this question to OpenSUSE forums.

Martin_helm's answer shows that the problem is distro-independent and the solution is trivial:

extern "C" {
#include <quadmath.h>
}

This works fine on all my machines. Program can be compiled with g++ prog.cpp -lquadmath.

Sergey
  • 7,985
  • 4
  • 48
  • 80
  • 4
    N.B. The `extern "C"` is not necessary with GCC 4.8 or later, because `` now adds that automatically when included by a C++ file. It is needed for GCC 4.6 and 4.7 though. – Jonathan Wakely Jun 09 '15 at 14:16