When I compile the pared-down program below, I get the following error from the linker:

$ gcc -std=c99 -O3 powltest.c -o powltest
/tmp/ccYkWTGI.o: In function `main':
powltest.c:(.text+0x7a): undefined reference to `powl'
collect2: ld returned 1 exit status

If I comment out the line with sscanf(), the compile is successful and the program runs correctly given the reduced functionality. It also works if I instead comment out the line containing powl()

#include <stdio.h>
#include <math.h>

int main(int argc, char *argv[])
{
    unsigned int bits = 5;
    unsigned int n = 0;
    unsigned long long start = 0;

    n = sscanf(argv[1], "%u", &bits);
    printf("%u\n", bits);
    start = powl(2, bits) - 1;
    printf("%llu\n", start);
}

Here are the versions:

$ gcc --version
gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1
$ ld --version
GNU ld (GNU Binutils for Ubuntu) 2.20

Same result on:

$ gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51)
$ ld --version
GNU ld version 2.17.50.0.6-14.el5 20061020

Runs:

$ ./powltest 42    # commented-out sscanf()
5
31
$ ./powltest 42    # commented-out powl()
42
0

What am I doing wrong?

有帮助吗?

解决方案

When you comment out the sscanf call, all of the variables have values known at compile time, and the compiler's optimiser is able to determine the result of the powl call without actually calling any functions declared in math.h.

When you uncomment the scanf call, the optimiser is unable to determine at compile-time the result of the powl call, so it must call the real powl function, which is in a separate library that you must link in with your program with -lm.

其他提示

Linking with the math library (-lm) removes the undefined reference to 'powl' error:

gcc -o test test.c -lm

This is also stated in the man pages for powl:

SYNOPSIS

#include <math.h>

double pow(double x, double y);
float powf(float x, float y);
long double powl(long double x, long double y);

Link with -lm.

EDIT: It only compiles for me when sscanf is commented out if it's also compiled with optimisations (-OX), dreamlax has the reason in his answer.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top