in reply to Re: [C Question] Determine if gcc provides erfl() function
in thread [C Question] Determine if gcc provides erfl() function

Do a test compile/link within Makefile.PL

I currently do that. The source includes a file named 'try.in' that contains:
/* Check whether erfl and isnanl can be linked. */ #include <stdio.h> #include <math.h> int main(void) { long double rop, op = 0.6L; int ret; rop = erfl(op); ret = isnanl(op); return 0; }
The Makefile.PL builds the executable:
my $out = `$cc $opt -o try.exe -x c try.in -lm 2>&1`;
and then runs it:
my $diag = $^O =~ /mswin32/i ? `try.exe 2>&1` : `./try.exe 2>&1`;
All of which is done successfully - though there's a warning about erfl() during the building of the executable.

However, it's just occurred to me that the executable actually doesn't do anything.
Could it be that success is achieved only because the problem I'm trying to expose is being optimised away ?

I'll rewrite the script so that it actually does something, and see if that catches the unavailability of erfl().
Or is the warning I'm seeing during the building of the executable sufficient to indicate that erfl() is unavailable ? That warning is:
try.in:12:8: warning: incompatible implicit declaration of built-in fu +nction 'erfl'

Is there anything else I might've missed ?
(I guess I'll try Devel::CheckLib if I can't get this right, myself.)

Thanks guys.

Cheers,
Rob

Replies are listed 'Best First'.
Re^3: [C Question] Determine if gcc provides erfl() function
by syphilis (Archbishop) on Jun 02, 2015 at 08:30 UTC
    However, it's just occurred to me that the executable actually doesn't do anything.
    Could it be that success is achieved only because the problem I'm trying to expose is being optimised away ?


    So, I made the test executable actually do something, and uploaded a new version (0.14) of Math::LongDouble.
    Unfortunately, I still get the same failure reports from Bingos' NetBSD smoker(s), and the test executable works fine.

    I guess the next thing is to try compiling the test executable using the same cflags ($Config{ccflags}) as are used during the module build.
    So, I'll try that.
    Should I also include $Config{ldflags} in the build of the test executable ?
    Any other ideas ? (Any other flags to include ?)

    Cheers,
    Rob
Re^3: [C Question] Determine if gcc provides erfl() function
by Anonymous Monk on Jun 02, 2015 at 14:14 UTC

    These functions are gcc builtins. They are optimised away. On linux, too. (Compile with -save-temps to see what is produced, or check the disassembly with objdump -d.)

    To do a proper test, use separate compilation units.

    /* test_isnanl.c */ #include <math.h> int test_isnanl(long double x) { return isnanl(x); }
    And link: cc main.o test_isnanl.o -lm && ./a.out || FAIL

    However, the above is not entirely future-proof either—it's defeated with link-time optimisation (-flto).
    So perhaps it would be better to
    #include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc, char *argv[]) { long double x = strtold(argv[1], NULL); printf("%d", isnanl(x)); printf("%Lf", erfl(x)); return 0; }

    Finally, if you limit your scope to the usual gcc/clang, then there is the -fno-builtin option that will make your original test work as is. This might be the best option of all.

      Compile with -save-temps to see what is produced, or check the disassembly with objdump -d

      Christ !! ... this is starting to look very difficult to understand.
      What sort of fuck-brained system allows the use of erfl() in a C file, but not in an XS file ?

      I'm also starting to worry that even if I get it working right for Bingos' smoker, I'll get it wrong elsewhere ... to the extent that the Makefile.PL will abort the build, even though the build would have succeeded had it been allowed to continue. This would be unforgivable, IMO. (My intention is simply to abort the build if erfl is not available.)

      I *think* there's an option to ban certain smokers (and/or testers) from testing modules, or something like that ... so I might investigate that path instead.
      I've really got better things to do than spend my time trying to figure out how Bingos' NetBSD systems work (for some questionable meaning of "work").

      Thanks for the responses, guys - they're all appreciated and any hostility detected in this post is not directed towards any of them.

      Cheers,
      Rob

        ... so I might investigate that path instead.
        Why? From what I see, the smoker is working as intended. The functions are not available on that platform and trying to use them ends in failure.

        Standard C gives the specification for many functions; this allows the compiler to make optimizations. Such as replacing a memcpy() with immediate moves. Or replacing a printf() by puts(), etc. Or eliminating a function call that has no effect...

        What you need to test is the presence of a function *in the system library*. Thus, for the purpose of said test, you can (a) make a sufficiently complicated test, avoiding constants; (b) disable the compilers awareness of those functions by disabling c99 mode, or by using -fno-builtin.

        Gcc defines its internal builtins with the expectation that fallback is available. But if the libm is deficient... Using gnu tools on a non-gnu platform, you may run into problems like that.