Undefined reference to pow collect2 error ld returned 1 exit status

C program undefined reference to pow error fix - Example C program to compute the periodic payment for a loan using pow function of math header file.

C program undefined reference to pow error

Why this undefined reference to pow error raised in compilation?

When we use the pow function or any other math functions from math header in c program on linux environment (RHEL, Fedora or CentOS), need to use -lm option for compilation.

otherwise you will get undefined reference to pow error, when you compile below program with no -lm option.

#include<stdio.h>                                                              
#include<math.h>                                                                
                                                                                
float PMT (int interest, int loan_amount, int total_months) {                   
 float rate, denominator;                                                       
 rate = (float) interest/100/12;                                                
 denominator = pow((1+rate), total_months)-1;                                   
 return (rate+(rate/denominator))*loan_amount;                                  
}                                                                               
void main()                                                                     
{                                                                               
 int loan_amount, loan_term_years, num_of_emi_per_year;                         
 float rate_of_interest, pmt_value;                                             
                                                                                
 printf("nEnter loan amount: ");                                               
 scanf("%d", &loan_amount);                                                     
                                                                                
 printf("nEnter loan tearm in years: ");                                       
 scanf("%d", &loan_term_years);                                                 
                                                                                
 printf("nEnter number of EMI per year: ");                                    
 scanf("%d", &num_of_emi_per_year);                                             
                                                                                
 printf("nEnter rate of interest: ");                                          
 scanf("%f", &rate_of_interest);                                                
 pmt_value= PMT(rate_of_interest, loan_amount, loan_term_years*num_of_emi_per_year);
 printf("nEMI: %f", pmt_value);                                                
}    

Output:

$ cc emi_calculator.c
/tmp/cc4v5U2R.o: In function `PMT':
emi_calculator.c:(.text+0x5a): undefined reference to `pow'
collect2: error: ld returned 1 exit status

To fix this issue, need to use -lm option in compilation command.

Output:

$ cc emi_calculator.c -lm
$ ./a.out 

Enter loan amount: 396000

Enter loan tearm in years: 4

Enter number of EMI per year: 12

Enter rate of interest: 15

EMI: 11020.946289

C program provides expected output when running a.out file once you compiled the program with -lm option.

If you want different name instead of a.out file, we need to use -o option to create executable file with custom name.

$ cc -o emi emi_calculator.c -lm
$ ./emi
Enter loan amount: 396000

Enter loan tearm in years: 4

Enter number of EMI per year: 12

Enter rate of interest: 15

EMI: 11020.946289

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//1. Разработать программу нахождения массива N последовательных значений функции y[i]=sin(2*PI*k*i/N) (i=0,1,2…N-1) с использованием ряда Тейлора. Пользователь задаёт значения   N и количество n членов ряда Тейлора. Для расчета  каждого члена ряда Тейлора запускается отдельный процесс. Каждый процесс выводит на экран  и в файл свой pid и рассчитанное значение ряда. Головной процесс считывает из файла значения  всех рассчитанных членов ряда Тейлора, суммирует их  и полученное значение y[i] записывает в файл. Проверить работу программы для N=256 n=5; N=1024  n=10 k=1.
 
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
 
double fix_x(double x)
{
    while (x > 2*M_PI)
        x = x - 2*M_PI;
    while (x < 0)
        x = x + 2*M_PI;
    return x;
}
 
double fact(double n) 
{
    return !n ? 1 : n * fact(n - 1);
}
 
void summa(int N, char* strName)
{    
        char z,ch[20],cc[20];
    char* pEnd;
        double mass[N];
        int i=0;
 
        FILE *file;
        char *fname = "/tmp/myFile.log";
        if ((file = fopen(fname,"r")) == NULL)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return; 
    }
        
        while (!feof(file))
    {      
        fscanf(file,"%c",&z);
        if (z == ' ')
        {
                        i = 0;
            while (1)
            {
               fscanf(file, "%c", &z);
               if ((z==' ') )
                break;
               else
               {
                ch[i]=z;
                i++;
                   }
 
            }
            ch[i] = '';
                        i = 0;
                        while (1)
                        {
                fscanf(file, "%c", &z);
                            if (z=='n')
                                 break;
                            else
                            {
                cc[i] = z;
                                i++;
                            }
                        }
                        cc[i] = '';
                        mass[atoi(ch)] += strtod(cc,&pEnd);
        }
 
    }
 
        if (fclose(file) == -1)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return; 
    }
 
 
        fname = "/tmp/myFile.rez";
        if ((file = fopen(fname,"w")) == NULL)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return; 
    }
 
        for (i=0; i<N; i++)
        {
              fprintf(file,"y[%d] = %0*.*fn",i,8,7,mass[i]);
        }
        if (fclose(file) == -1)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return; 
    }
}
 
void element(int N, int n, int i, int j, char* strName)
{
    double x,el=0;
    int f = 0;
    FILE *file;
    char *fname = "/tmp/myFile.log";
    
    if ((file = fopen(fname,"a")) == NULL)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return; 
    }
 
    x = fix_x(2*M_PI*i/N);
    if (x > M_PI)
    {
        f = 1;
        x = x - M_PI; 
    }
 
    if (x > M_PI/2 )
    { 
        x = M_PI - x;
    }
 
    el = (pow((-1),j) * pow(x,(2*j+1)))/(fact(2*j+1) ) ;
 
    if (f == 1)
    {
        el = (-1)*el;
    }
    if ((fprintf(file,"%d: %d %0*.*fn",getpid(),i,8,7,el)) == -1)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return;
    }
 
    printf("%d: %d %0*.*fn",getpid(),i,8,7,el);
    
    if (fclose(file) == -1)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return; 
    }
}
 
 
int main(int argc, char *argv[])
{
    char strName[strlen(argv[0])];
  
        int k=0;
        int p=0;
 
    for (p=2; p<strlen(argv[0]); p++)
    {
        strName[k] = argv[0][p];
        k++;
    }
    strName[k] = '';
    
        if (argc !=3 )
        {
        fprintf(stderr,"%s: %sn", strName, strerror(errno)); 
        return 1;
    }
 
    FILE *file;
        char *fname = "/tmp/myFile.log";
 
        if ((file = fopen(fname,"w")) == NULL)
    {
        fprintf(stderr,"%s: %s: %sn", strName, strerror(errno), fname); 
        return 1;
    }
 
        //fclose (file);
 
    int N,n,i,j,count,tmp;
        pid_t pid;
 
    int status;
 
        N = atoi(argv[1]);
    n = atoi(argv[2]);
        count = n;
    tmp = 0;
 
    for (i=0; i<N; i++)
    {
        for (j=0; j<n; j++)
                {
           pid = fork();
                   if (pid > 0)
           {
            tmp++;
                        if (tmp > count )
            {
                //wait();
                tmp--;
            }
           }
 
                   if (pid == -1)
           {
                    fprintf(stderr,"%s: %sn", strName, strerror(errno)); 
                        return 0;
           }
                   else 
                        if (pid == 0)
                        { 
               element(N,n,i,j, strName);
                           exit(1);
                }  
         }
         
    }
 
    while (wait(&status) > 0);      
 
        summa(N, strName);
        
    return 0;
}

Example

One of the most common errors in compilation happens during the linking stage. The error looks similar to this:

$ gcc undefined_reference.c 
/tmp/ccoXhwF0.o: In function `main':
undefined_reference.c:(.text+0x15): undefined reference to `foo'
collect2: error: ld returned 1 exit status
$

So let’s look at the code that generated this error:

int foo(void);

int main(int argc, char **argv)
{
    int foo_val;
    foo_val = foo();
    return foo_val;
}

We see here a declaration of foo (int foo();) but no definition of it (actual function). So we provided the compiler with the function header, but there was no such function defined anywhere, so the compilation stage passes but the linker exits with an Undefined reference error.
To fix this error in our small program we would only have to add a definition for foo:

/* Declaration of foo */
int foo(void);

/* Definition of foo */
int foo(void)
{
    return 5;
}

int main(int argc, char **argv)
{
    int foo_val;
    foo_val = foo();
    return foo_val;
}

Now this code will compile. An alternative situation arises where the source for foo() is in a separate source file foo.c (and there’s a header foo.h to declare foo() that is included in both foo.c and undefined_reference.c). Then the fix is to link both the object file from foo.c and undefined_reference.c, or to compile both the source files:

$ gcc -c undefined_reference.c 
$ gcc -c foo.c
$ gcc -o working_program undefined_reference.o foo.o
$

Or:

$ gcc -o working_program undefined_reference.c foo.c
$

A more complex case is where libraries are involved, like in the code:

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

int main(int argc, char **argv)
{
    double first;
    double second;
    double power;

    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s <denom> <nom>n", argv[0]);
        return EXIT_FAILURE;
    }

    /* Translate user input to numbers, extra error checking
     * should be done here. */
    first = strtod(argv[1], NULL);
    second = strtod(argv[2], NULL);

    /* Use function pow() from libm - this will cause a linkage 
     * error unless this code is compiled against libm! */
    power = pow(first, second);

    printf("%f to the power of %f = %fn", first, second, power);

    return EXIT_SUCCESS;
}

The code is syntactically correct, declaration for pow() exists from #include <math.h>, so we try to compile and link but get an error like this:

$ gcc no_library_in_link.c -o no_library_in_link
/tmp/ccduQQqA.o: In function `main':
no_library_in_link.c:(.text+0x8b): undefined reference to `pow'
collect2: error: ld returned 1 exit status
$

This happens because the definition for pow() wasn’t found during the linking stage. To fix this we have to specify we want to link against the math library called libm by specifying the -lm flag. (Note that there are platforms such as macOS where -lm is not needed, but when you get the undefined reference, the library is needed.)

So we run the compilation stage again, this time specifying the library (after the source or object files):

$ gcc no_library_in_link.c -lm -o library_in_link_cmd
$ ./library_in_link_cmd 2 4
2.000000 to the power of 4.000000 = 16.000000
$

And it works!

Я пытаюсь сделать простой калькулятор Фибоначчи на C, но при компиляции gcc говорит мне, что мне не хватает функций pow и floor. Что случилось?

код:

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

int fibo(int n);

int main() {
        printf("Fib(4) = %d", fibo(4));
        return 0;
}

int fibo(int n) {
        double phi = 1.61803399;

        return (int)(floor((float)(pow(phi, n) / sqrt(5)) + .5f));
}

выход:

gab@testvm:~/work/c/fibo$ gcc fib.c -o fibo
/tmp/ccNSjm4q.o: In function `fibo':
fib.c:(.text+0x4a): undefined reference to `pow'
fib.c:(.text+0x68): undefined reference to `floor'
collect2: ld returned 1 exit status

5 ответов


вам нужно скомпилировать с флагом ссылке -lm, например:

gcc fib.c -lm -o fibo

это скажет gcc связать ваш код с математическим lib. Просто не забудьте поставить флаг после объекты, которые вы хотите связать.


добавить-lm в параметры ссылки, так как pow () и floor () являются частью математической библиотеки:

gcc fib.c -o fibo -lm

в интересах тех, кто читает это позже, вам нужно связать с ним, как сказал Фред:

gcc fib.c -lm -o fibo

один хороший способ узнать, какую библиотеку вам нужно связать, — проверить справочную страницу, если она существует. Например, man pow и man floor оба скажут вам:

ссылке -lm.

объяснение связывания математической библиотеки в программировании на C -связывание в C


в отношении ответа, предоставленного Fuzzy:

на самом деле я должен был сделать что-то немного другое.

проект — > свойства — > сборка C/C++ — > настройки — > Компоновщик GCC C — > библиотеки

нажмите маленький зеленый значок Добавить, введите m и нажмите ok. Все в этом окне автоматически-L применяется к нему, так как это библиотека.


чтобы найти точку, где добавить-lm в Eclipse-IDE, действительно ужасно, поэтому мне потребовалось некоторое время.

Если кто-то еще также использует Edlipse, вот как добавить команду:

Project — > Properties — > C / C++ Build — > Settings — > gcc c Linker — > Miscelleaneous — > флаги компоновщика: в это поле добавьте команду-lm


Понравилась статья? Поделить с друзьями:
  • Undefined reference to main collect2 error ld returned 1 exit status
  • Undefined reference to collect2 exe error ld returned 1 exit status
  • Undefined object 7 error index primary does not exist
  • Undefined function or variable matlab как исправить
  • Undefined function matlab error