The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > High Level Programming
Google UNIX.COM


High Level Programming Post questions about C, C++, Java, SQL, and other programming languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
awk Shell Script error : "Syntax Error : `Split' unexpected Herry UNIX for Dummies Questions & Answers 2 03-17-2008 08:16 AM
error during run: St9bad_alloc - Getting this error while using some conversion progr sathu_pec Shell Programming and Scripting 1 01-20-2008 11:38 PM
I got error like...syntax error on line 1, teletype koti_rama UNIX for Advanced & Expert Users 2 07-07-2007 04:35 PM
error reading sections error at install doelman SUN Solaris 2 02-05-2007 09:21 AM
Error: Internal system error: Unable to initialize standard output file firkus UNIX for Dummies Questions & Answers 2 10-25-2005 12:23 PM

Reply
 
Submit Tools LinkBack Thread Tools Display Modes
  #15  
Old 07-11-2006
Registered User
 

Join Date: Jun 2006
Location: Malaysia
Posts: 14
Quote:
Originally Posted by Corona688
This might best be shown by example.

In a directory by itself, create this file:
Code:
// main.c
#include <stdio.h>

int main(int argc, char *argv[])
{
  int n;
  fprintf(stderr,"main(%d,[",argc);
  for(n=0; n<argc; n++)
    fprintf(stderr," '%s'",argv[n]);
  fprintf(stderr," ]);\n");
  return(0);
}
Then compile and run it like this:
Code:
# gcc main.c -o main
# ./main
main(1,[ './main' ]);
#
That works, but what you might not realize is that gcc is actually doing two steps, not one -- compilation, then linking. The compilation stage converts C code into assembly language, the linking stage ties everything together into an executable. Let's break it into two steps:
Code:
# gcc -c main.c -o main.o
# gcc main.o -o main
# ./main
main(1,[ './main' ]);
#
That's what gcc is ACTUALLY doing... converts the C file into an object file(.o), then links the object file into an executable.

Now let's try and use a function from another .c file. First, create this file:
Code:
// library.c
#include <stdio.h>

int library_function(int c)
{
  fprintf(stderr,"library_function(%d)\n",c);
  return(c-3);
}
Then, modify main.c to use it like this:
Code:
#include <stdio.h>

extern int library_function(int c);

int main(int argc, char *argv[])
{
  int n;
  fprintf(stderr,"main(%d,[",argc);
  for(n=0; n<argc; n++)
    fprintf(stderr," '%s'",argv[n]);
  fprintf(stderr," ]);\n");

  printf("library_function(%d) returns %d\n",32,library_function(32));

  return(0);
}
Finally, let's see what happens when we try and compile it, then link it:
Code:
# gcc -c main.c -o main.o
# gcc main.o -o main
main.o: In function `main':
main.c:(.text+0x86): undefined reference to `library_function'
collect2: ld returned 1 exit status
#
It doesn't work. It compiles it fine since there's no syntax errors in the program, but the function it wants is not in main.o! To get that function, we'll need to give it library.o too.
Code:
# gcc -c main.c -o main.o
# gcc -c library.c -o library.o
# gcc main.o library.o -o main
# ./main
main(1,[ './main' ]);
library_function(32)
library_function(32) returns 29
#
It works!

Now, if you want your makefile to do that, you need to tell it that the output file needs main.o and library.o. Here's a simple makefile:
Code:
main:main.o library_function.o
        $(CC) main.o library_function.o $(LDFLAGS) -o $@
clean:
        rm -f main main.o library_function.o
With that makefile in the main directory, let's try it:
Code:
# make clean
rm -f main main.o library_function.o
# make main
cc    -c -o main.o main.c
cc    -c -o library.o library.c
cc main.o library.o  -o main
# ./main
main(1,[ './main' ]);
library_function(32)
library_function(32) returns 29
#
It works!

So there you go. You'll need to find the .c file that these missing functions reside in, convert it to an object, then link it into your executable.

Dear Corona

I have to call you my coach. Thank you very much for taking your time to put all this line and explain for me. I learn a lot from explaination.

Here is what I found by following your instruction,

I ran the first program using gcc and it work, and second program with function and using gcc and it work.

Then when it came to makefile one. I have receive the below error

couliba@linux:~/main> make clean
rm -f main main.o library_function.o
couliba@linux:~/main> make main
cc -c -o main.o main.c
make: *** No rule to make target `library_function.o', needed by `main'. Stop.
couliba@linux:~/main>


Do not u think, the problem is my lunix installation. Because this is my notebook I just recently install lunix.

Any help is appreciated
Reply With Quote
Forum Sponsor
  #16  
Old 07-11-2006
Registered User
 

Join Date: Aug 2005
Location: Saskatchewan
Posts: 979
Simply the wrong filename. It goes by file extension, it does not know how to make a library_function.o when there's no library_function.c . Change library_function.c and library_function.o to library.c and library.o respectively and it should work.

Come to think of it, that was a mistake in my example wasn't it? Oops. Fixed.

Last edited by Corona688; 07-11-2006 at 07:26 AM.
Reply With Quote
  #17  
Old 07-12-2006
Registered User
 

Join Date: Jun 2006
Location: Malaysia
Posts: 14
Quote:
Originally Posted by Corona688
Simply the wrong filename. It goes by file extension, it does not know how to make a library_function.o when there's no library_function.c . Change library_function.c and library_function.o to library.c and library.o respectively and it should work.

Come to think of it, that was a mistake in my example wasn't it? Oops. Fixed.

Dear Corona

Thank you very, I did the changes and it work for the simple.

but

I applied to my code and I still receive the smilar erorr but not as much as earlier. I have created object files for all my C files. You may need view the below tag.

Quote:

couliba@linux:~/usr/ga> make find_rules
cc -c -o find_rules.o find_rules.c
cc -c -o find_util.o find_util.c
cc -c -o find_functions.o find_functions.c
cc -c -o util.o util.c
cc -c -o gp.o gp.c
cc -c -o gp_util.o gp_util.c
cc find_rules.c find_util.c find_functions.c util.c gp.c gp_util.c -o find_rules
/tmp/ccRkjXgc.o(.text+0x33): In function `get_boolean':
util.c: warning: the `gets' function is dangerous and should not be used.
/tmp/cc1LxypZ.o(.text+0xa40): In function `read_data':
find_util.c: undefined reference to `log'
/tmp/cc1LxypZ.o(.text+0xaa1):find_util.c: undefined reference to `log'
/tmp/cc1LxypZ.o(.text+0xdf4): In function `compounded_return':
find_util.c: undefined reference to `log'
/tmp/cc1LxypZ.o(.text+0xeeb): In function `simulate_price':
find_util.c: undefined reference to `exp'
/tmp/cc1LxypZ.o(.text+0x10a6): In function `compute_return':
find_util.c: undefined reference to `log'
/tmp/cc1LxypZ.o(.text+0x11ed): In function `test_statistic':
find_util.c: undefined reference to `pow'
/tmp/cc1LxypZ.o(.text+0x1277):find_util.c: undefined reference to `pow'
/tmp/cc1LxypZ.o(.text+0x1311):find_util.c: undefined reference to `pow'
/tmp/cc1LxypZ.o(.text+0x1b91): In function `compute_t':
find_util.c: undefined reference to `sqrt'
/tmp/cc1LxypZ.o(.text+0x1c3c): In function `compute_stdev':
find_util.c: undefined reference to `pow'
/tmp/cc1LxypZ.o(.text+0x1c51):find_util.c: undefined reference to `sqrt'
/tmp/cc1LxypZ.o(.text+0x1c81): In function `simple_return':
find_util.c: undefined reference to `exp'
/tmp/ccLquGy3.o(.text+0x627): In function `eval_average':
find_functions.c: undefined reference to `floor'
/tmp/ccLquGy3.o(.text+0x739): In function `eval_maximum':
find_functions.c: undefined reference to `floor'
/tmp/ccLquGy3.o(.text+0x87c): In function `eval_minimum':
find_functions.c: undefined reference to `floor'
/tmp/ccLquGy3.o(.text+0x9ad): In function `eval_slope':
find_functions.c: undefined reference to `floor'
/tmp/ccLquGy3.o(.text+0xaca): In function `eval_volatility':
find_functions.c: undefined reference to `floor'
/tmp/ccLquGy3.o(.text+0xb58):find_functions.c: undefined reference to `pow'
/tmp/ccLquGy3.o(.text+0xbf2): In function `eval_lag':
find_functions.c: undefined reference to `floor'
/tmp/ccrHQ96N.o(.text+0xe0c): In function `select_rank':
gp_util.c: undefined reference to `pow'
/tmp/ccrHQ96N.o(.text+0xe21):gp_util.c: undefined reference to `floor'
collect2: ld returned 1 exit status
make: *** [find_rules] Error 1
Any help is very much appreciated.

Thank you dear
Reply With Quote
  #18  
Old 07-12-2006
Registered User
 

Join Date: Aug 2005
Location: Saskatchewan
Posts: 979
Don't call people 'dear' unless you're married to them.

Your makefile is wrong. It's compiling all the C files together instead of all the objects. Which, while it will work, is awkward and hard to debug, avoids all the advantages of using a makefile in the first place, and does all the work twice.

Instead of
Code:
cc file.c file2.c file3.c ... -o exec
it should do
Code:
cc file.o file2.o file3.o ... -o exec
Some of those missing functions are functions you still haven't compiled, but a few are from the C math library. At the top of your makefile, add the line:
Code:
LDFLAGS=-lm
That will tell it to link in the math library.

If you're still missing functions, you're missing a file. Maybye whoever gave you the code didn't give you all of it.
Reply With Quote
  #19  
Old 07-12-2006
Registered User
 

Join Date: Jun 2006
Location: Malaysia
Posts: 14
Smile

Quote:
Originally Posted by Corona688
Don't call people 'dear' unless you're married to them.

Your makefile is wrong. It's compiling all the C files together instead of all the objects. Which, while it will work, is awkward and hard to debug, avoids all the advantages of using a makefile in the first place, and does all the work twice.

Instead of
Code:
cc file.c file2.c file3.c ... -o exec
it should do
Code:
cc file.o file2.o file3.o ... -o exec
Some of those missing functions are functions you still haven't compiled, but a few are from the C math library. At the top of your makefile, add the line:
Code:
LDFLAGS=-lm
That will tell it to link in the math library.

If you're still missing functions, you're missing a file. Maybye whoever gave you the code didn't give you all of it.

Coach
Thank you very much the code is working very well now. You make it successful. I appreciate so much all your efort and sharing of knowledge.

Acctually all files are completed. I have test the codes in my friend's notebook last three month ago before I bought my notebook and it work without any problem. However, when I bought my own notebook and install linux then all this problem start to come out. By the way my friend is using suse 10 and I am using suse 9.3. I am not sure if that can make any different.

I have one concern to ask you. After add -lm to the makefile, there was only one warning appeared saying this:

/tmp/ccYaBtHR.o (.text+0X33): In function 'get_boolean':
util.c:warning: the 'gets' function is dangerouns and should not be used.

To avoid this warning what I do, I went to util.c file and comment out gets(line); then the program work very well. Any idea why this warning. Is possible to run the program without commenting out this line?

Again thank you very much
Reply With Quote
  #20  
Old 07-14-2006
Registered User
 

Join Date: Aug 2005
Location: Saskatchewan
Posts: 979
Without seeing util.c I can't know what it's using gets for. gets reads a string from standard input, storing it as a character array terminated by a NULL character.

The problem with gets is that it takes an unlimited amount of input. It does not know how much space is available in the buffer. For instance:
Code:
#include <stdio.h>
int main()
{
  char buf[16];
  gets(buf);
  printf("You typed %s\n",buf);
  return(0);
}
If I typed "486193474587130958712057190856714890651618476" and hit enter, it would dump that entire string into that buffer of 16 bytes, which obviously isn't large enough to hold it. The remainder of it would get crammed into whatever bytes of memory trail after the buffer, which may be unused, or used for other variables, or part of the call stack, etc. When overflows like this happen they can be VERY hard to debug since by nature buffer overflows overwrite memory they're not supposed to. It's also a security risk -- if someone knows there's a buffer they can overflow, they can write to variables after it in memory, setting them to whatever values they want!

This is much safer:
Code:
#include <stdio.h>

int main()
{
  char buf[16];
  fgets(buf,16,stdin);
  printf("You typed %s\n",buf);
  return(0);
}
This will not overflow the buffer, it will only read a maximum of 15 bytes.
Reply With Quote
Google The UNIX and Linux Forums
Reply

Tags
linux

Thread Tools
Display Modes




All times are GMT -7. The time now is 07:39 AM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited.
The UNIX and Linux Forums Content Copyright ©1993-2008. All Rights Reserved.Ad Management by RedTyger Visit The Complex Event Processing Blog

Content Relevant URLs by vBSEO 3.2.0