sscanf () приводит к сбою ссылки при наличии функции powl () - PullRequest
1 голос
/ 05 января 2012

Когда я компилирую урезанную программу ниже, я получаю следующую ошибку от компоновщика:

$ 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

Если я закомментирую строку с sscanf(), компиляция пройдет успешно, и программа запуститсяправильно, учитывая ограниченную функциональность.Это также работает, если я вместо этого закомментирую строку, содержащую 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);
}

Вот версии:

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

Тот же результат:

$ 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

Прогоны:

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

Что я делаю не так?

Ответы [ 2 ]

6 голосов
/ 05 января 2012

Когда вы комментируете вызов sscanf, все переменные имеют значения, известные во время компиляции, и оптимизатор компилятора может определить результат вызова powl без фактического вызова каких-либо функций, объявленных в math.h .

Когда вы раскомментируете вызов scanf, оптимизатор не может определить во время компиляции результат вызова powl, поэтому он должен вызвать реальную функцию powl, которая находится в отдельной библиотеке, которую вы должен связать вашу программу с -lm.

3 голосов
/ 05 января 2012

При связывании с математической библиотекой (-lm) устраняется ошибка undefined reference to 'powl':

gcc -o test test.c -lm

Это также указано в справочных страницах для powl:

СИНТАКСИС

#include <math.h>

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

Связь с -lm.

РЕДАКТИРОВАТЬ: Он компилируется для меня только когда sscanf закомментирован, если он также скомпилирован с оптимизацией (-OX), dreamlax имеет причину в своем ответе. 1026 *

...