So I have the following code:
#include <stdio.h>
#define MAX(a,b) (a) > (b) ? a : b
int abs(int a)
{
if (a > 0)
return a;
else
return a*-1;
}
inline int avg(int a, int b)
{
return (a+b)/2;
}
int math_max(int a, int b)
{
return (avg(a,b)+abs(avg(a,b)-b));
}
int main(int argc, char** argv)
{
return 0;
}
When I compile it: gcc -g test.c -o test
I get:
/tmp/ccZbHEju.o: In function `math_max':
test.c:(.text+0x33): undefined reference to `avg'
test.c:(.text+0x44): undefined reference to `avg'
collect2: error: ld returned 1 exit status
I can fix this by removing the inline notation from avg, but I don't know why I'm getting undefined references if its inline - I thought the compiler was supposed to take care of that
Anyone care to explain?
** Adding more information **
For those who can't reproduce, I'm using:
gcc --version gcc (GCC) 5.3.0 Copyright (C) 2015 Free Software
Foundation, Inc. This is free software; see the source for copying
conditions. There is NO warranty; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
Compiling this code with without linking generates the following:
[ishaypeled@arania test]$ gcc -c test.c -o ./test.o
[ishaypeled@arania test]$ readelf -s ./test.o
Symbol table '.symtab' contains 13 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 6
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 5
8: 0000000000000000 25 FUNC GLOBAL DEFAULT 1 abs
9: 0000000000000019 43 FUNC GLOBAL DEFAULT 1 max
10: 0000000000000044 69 FUNC GLOBAL DEFAULT 1 math_max
11: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND avg
12: 0000000000000089 18 FUNC GLOBAL DEFAULT 1 main
Which clearly shows avg as NOTYPE and UND - this is why the linker failed... I have no idea why that happens. I also examined the preprocessor output from gcc:
[ishaypeled@arania test]$ gcc test.c -E
# 5 "test.c"
int abs(int a)
{
if (a > 0)
return a;
else
return a*-1;
}
int max(int a, int b)
{
return ((a+b)+abs(a-b))/2;
}
inline int avg(int a, int b)
{
return (a+b)/2;
}
int math_max(int a, int b)
{
int avg_calc = avg(a,b);
int distance_from_avg = abs(avg_calc-a);
int res = avg_calc+distance_from_avg;
return res;
}
int main(int argc, char** argv)
{
# 44 "test.c"
return 0;
}
Looks perfectly fine, avg appears before the usage in math_max.
STDC version: 201112
__GNUC__ defined