|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| ||||||||||||||||||||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Undefined reference to 'pow' (newbie mistake)
Am using the generic cc C compiler on Ubuntu, and working my way through the ANSI C book by Kernighan and Ritchie. Am on exercise 2-3 and having a problem compiling. The program isn't finished, and I just have a comment in for the main function for what it's suppose to do and pass to my htoi function. Just curious as to what I'm doing wrong with the htoi function to get these errors, so I can finish working on the assignment problem:
paul@paul-laptop:~/Desktop/C/2/2-3$ cc main.c /tmp/ccm3DUVO.o: In function `htoi': main.c:(.text+0xca): undefined reference to `pow' main.c:(.text+0x136): undefined reference to `pow' main.c:(.text+0x191): undefined reference to `pow' main.c:(.text+0x1ec): undefined reference to `pow' main.c:(.text+0x247): undefined reference to `pow' /tmp/ccm3DUVO.o:main.c:(.text+0x2a2): more undefined references to `pow' follow collect2: ld returned 1 exit status Code:
/*
Exercise 2-3. Write a function htoi(s), which converts a string of hexadecimal digits
(including an optional 0x or 0X) into its equivalent integer value. The allowable digits are 0
through 9, a through f, and A through F.
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAXI 1000
double htoi(char s[], int len);
int main()
{
char hex[MAXI];
/*
Take a string of characters input by user, verify it's in the
format of a hex number, then use htoi() to turn it from a hex
string to a double number. Use strlen to pass to htoi.
*/
return 0;
}
double htoi(char s[], int len)
{
double n = 0;
int j = 0;
int i;
if(len >= 2 && s[0] == 0 && (s[1] == 'x' || s[1] == 'X'))
{
s[1] = 0;
s[0] = 0;
}
for(i = len; i >= 0; i--, j++)
{
if(s[i] >= '0' && s[i] <= '9')
n += pow(16.0, (double) j ) * (s[i] - '0');
else if(s[i] == 'A' || s[i] == 'a')
n += pow(16.0, (double) j) * 10;
else if(s[i] == 'B' || s[i] == 'b')
n += pow(16.0, (double) j) * 11;
else if(s[i] == 'C' || s[i] == 'c')
n += pow(16.0, (double) j) * 12;
else if(s[i] == 'D' || s[i] == 'd')
n += pow(16.0, (double) j) * 13;
else if(s[i] == 'E' || s[i] == 'e')
n += pow(16.0, (double) j) * 14;
else if(s[i] == 'F' || s[i] == 'f')
n += pow(16.0, (double) j) * 15;
}
return n;
}
Thanks! |
|
#2
|
||||
|
||||
|
You need to link with the maths library
gcc prog.c -lm That's minus-L-M (all in lowercase)
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. |
|
#3
|
|||
|
|||
|
Quote:
Ah, awesome. Thanks. How do you know when you need to do that sort of thing when compiling? It's more than likely going to come up more often, may as well know what I'm doing Also, why gcc rather than cc? (Am using C, not C++, if that makes any difference since I know gcc is what's used for C++ compiling) |
|
#4
|
||||
|
||||
|
Quote:
I imagine that cc is simply an alias for gcc for UNIX compatability. GCC stands for GNU Compiler Collection (although formerly was simply GNU C Compiler I think). For C++ compilation it is common to use g++. The only difference between gcc and g++ is that g++ links stdlibc++ as a default library as well as libc and libm. They can both compile code in C, C++ and Objective-C and are simply differently configured builds of the same compiler driver. Regarding your original question I was under the impression that libm was a default library for gcc builds so you probably did not need the -lm switch at all. Perhaps that is the difference between gcc and cc in this case. The standard library is divided into the C math library, and everything else (libm and libc). Normally as I said you do not need to explicitly link either, but there are (rare) circumstances where you might. Libc also contains system calls that are not part of the standard library (such as fork, and filesystem functions). If a call you are using is not in one of these, you will also need to link its archive. This should be clear from the documentation. Clifford |
|
#5
|
||||
|
||||
|
I am pretty sure that cc is a POSIX compliant alias for whatever the system compiler is on most *nix systems. It probably just invokes gcc on most Linux systems these days, but a user can set this alias in one or more of their shell configuration files.
__________________
My worst nightmare was a pointless infinite loop. Work in progress; don't poke the curmudgeon! http://www.odonahue.com/ |
|
#6
|
|||||
|
|||||
|
Quote:
1) When you receive error messages from the linker about undefined symbols (the messages you've seen are an example of that) they indicate the linker has not found a function called by your code so cannot build your executable. 2) If the reported functions are standard (i.e. in the standard C or C++ libraries) then that means you have not provided the name of one or more required libraries to the linker. 3) If the function is a standard math function, then it is a fair bit the missing library is the math library. 4) Under unix, by convention, the math library is (usually) specified to the compiler and linker using the command line option "-lm". Quote:
Depends on your system. Under most flavours of linux, cc is often a synonym for gcc. Under other flavours of unix, cc is a different compiler (supplied by the OS vendor). Quote:
That's not actually true. gcc is a driver program that, by default, assumes it is compiling C code. Depending on various options, and files supplied on the command line, it can compile code from other languages and also drive the linker (to produce executables). g++ is normally provided with gcc, and is a driver that, by default, assumes it is compiling C++ code. [The details are a bit more complicated than that, but I won't bother intimidating you with the details.].
__________________
Right 98% of the time, and don't care about the other 3%. |
|
#7
|
|||
|
|||
|
Still having problems. Rewrote the program to try and get a hang over it, so here it goes, and here's the error messages:
Code:
/*
Exercise 2-3. Write a function htoi(s), which converts a string of hexadecimal digits
(including an optional 0x or 0X) into its equivalent integer value. The allowable digits are 0
through 9, a through f, and A through F.
* user inputs a string of characters -> getLine
* verify string of characters fits the hex format
-> have in a nested loop that runs through testing to see if it fits against an array like hexDigits[] = "0123456789ABCDEF" after toupper()ing string. once it matches, continue through, else if hexDigits[i] = '\0', isHex = 0;
* convert hex characters to decimal by multiplying through on a base 16 system
- multiply digit by 16, assigning values to the letters as if > '9', (s[i] - 'A' + 1) * pow(16, pow) else (s[i] - '0') * pow(16, pow)
* display number
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define MAXI 30
long htoi(char array[], int len);
int isHex(char array[], int len);
int getLine(char array[], int lim);
main()
{
char hexDigits[MAXI];
long int deci;
int hexLen;
printf("input digits");
hexLen = getLine(hexDigits, MAXI);
while(isHex(hexDigits, hexLen) != 1)
{
printf("input digits again");
getLine(hexDigits, MAXI);
}
deci = htoi(hexDigits, hexLen);
printf("number is: %d", deci);
}
long htoi(char array[], int len)
{
long num = 0;
int i, power;
for(i = 0, power = len - 1; i < len;i++, power--)
if(array[i] > '9')
num += (array[i] - 'A' + 11) * pow(16, power);
else
num += (array[i] - '0') * pow(16, power);
return num;
}
int isHex(char array[], int len)
{
char hexDigits[16] = "0123456789ABCDEF";
toupper(array);
int i, j;
int ishex = 0;
//If leading 0X or 0x, convert x to 0.
if(len >= 2 && array[0] == '0' && array[1] == 'X')
array[1] = 0;
for(i = 0; array[i] < len;i++)
{
ishex = 0;
for(j = 0;j < 16;j++)
if(array[i] == hexDigits[j])
ishex = 1;
if(ishex == 0) break;
}
return ishex;
}
//All strings of hex will end in \0, so len-1 returned to work with other functions
int getLine(char array[], int lim)
{
int c, i;
for(i = 0; i < lim-1 && (c = getChar()) != EOF && c != '\n'; i++)
{
array[i] = c;
}
if(c == '\n')
{
array[i] = c;
i++;
}
array[i] = '\0';
return i-1;
}
Code:
paul@paul-laptop:~/Desktop/C/2/2-3$ gcc -lm main.c main.c: In function ‘isHex’: main.c:59: warning: passing argument 1 of ‘toupper’ makes integer from pointer without a cast /tmp/ccOSvZ0y.o: In function `getLine': main.c:(.text+0x2a4): undefined reference to `getChar' collect2: ld returned 1 exit status paul@paul-laptop:~/Desktop/C/2/2-3$ |
|
#8
|
|||
|
|||
|
getchar(), not getChar(). Capitalization matters. Incidentally, this is what the compiler error was telling you. It says "undefined reference to `getChar'", telling you exactly where to look too.
I tell you this because you need to start reading the error messages, as opposed to checking if they simply exist or not. If you don't understand the error messages (that's OK), ask, because you will keep getting them as you write more programs, and you need to learn to understand them.
__________________
When you ask a question, be prepared to tell us: what have you tried? If you think you don't need to try anything, we will never be interested in helping you. If you agree with the link, and you refuse to answer that question, you are being a hypocrite. Need help with broken code? Your question should be like a good bug report: (1) It has the smallest number of steps to reproduce the problem you see (2) It tells us precisely what you expected to see and (3) It tells us what you saw and how it differed from what you expected. We need all three to help you. Want better answers? Tell us what you Googled for and what steps you took to answer your own question. |
|
#9
|
|||
|
|||
|
Heh *retarded* I didn't even notice it wasn't capitalized. I checked the line out to see if I had put in the parameters wrong in a few places and all
Thanks. Since pointers haven't been covered in the book yet, how do I go about fixing the toupper problem? I tried adding a (char) caster in the line toupper( (char) array); but that gives another warning about integer and char being different sizes.Gotta fix a logic error with isHex now, too :/ it's not leaving the loop for that one. Should be simple enough to fix that though. Got the htoi part working ![]() |
|
#10
|
||||
|
||||
|
The toupper() function takes an int and only works on one character at a time. You can't use it to make a whole C string uppercase without writing a loop to iterate over the characters. When you get errors for function parameters always check the docs for that function.
This should help: http://www.cplusplus.com/reference/...cctype/toupper/ |
|
#11
|
|||
|
|||
|
EDIT (multiple times): My question was semi-answered actually above, but always check documentation. My question is still worth pondering over, I suppose.
Quote:
You haven't covered pointers at all, but you can still investigate. First, tell me what you believe toupper does, and what parameter type it takes? What you want is to have all the characters in the array converted to their uppercase equivalents. The question is, does toupper(array) do what you want? It doesn't actually, but here's an important question you should ask yourself. Where did you come up with toupper(array)? Where did you come up with toupper in the first place? What documentation did you read? What did this documentation tell you. Because your usage of toupper is horribly incorrect, check the documentation once and see if you spot the obvious mistake. |
|
#12
|
|||
|
|||
|
Yeah, I got how toupper works now for C/C++, heh. I was thinking it worked along the lines of string.toUpperCase(); in Java.
|
![]() |
| Viewing: Dev Shed Forums > Programming Languages > C Programming > Undefined reference to 'pow' (newbie mistake) |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|
|