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