2012-01-05 2 views
1

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

$ 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 

Что я делаю w Ронг?

ответ

6

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

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

+0

Хорошее объяснение того, почему комментирование 'sscanf' работает, когда оптимизация включена в компиляторе. – AusCBloke

3

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

gcc -o test test.c -lm 

Это также говорилось на страницах руководства для 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: Он компилирует только для меня, когда sscanf закомментирован, если он также скомпилирован с оптимизацией (-OX), dreamlax имеет причину в его ans WER.

+0

Согласен с AusCBloke - со страницы руководства "Ссылка на -lm." –

+0

Это не объясняет другое явление, когда оно компилируется и работает правильно без вызова 'sscanf'. – dreamlax

+0

@dreamlax отличный момент - я не читал вопрос подробно - приятно найти. –