Menu

Problem with function and linker

Anonymous
2008-12-01
2012-09-26
  • Anonymous

    Anonymous - 2008-12-01

    Howdy to all. I am a newbee to programming. Just trying to learn some C programming to keep the brain from going completely to hell :)

    I have been working from the book:
    C All-In-One-Desk Reference for Dummies and wanted to expand on one of the example programs and tried to use a couple of functions but have been frustrted by a linker error.

    Hopefully someone can tell me what I have done wrong.

    Here it is:

    (1) What version number of Dev are you using, with what OS? (Note that terms like "Newest" or "The one off the CD" are not version numbers)

    (2) Provide a simple example program that shows the effect you are seeing. If your program is long, try to construct a simple, focused example program. Remember, it is easier for someone to help you with a simple example program that with a code fragment of a long program.

    (3) Post your FULL compile log. Its on the tab labeled "Compile Log". To copy it, grab the text with the mouse as you normally would, and click the right mouse button to bring up the copy menu. If the log is very long, then start at the beginning, and grab the first 5 or so errors.

    I am using version number 4.9.9.2
    I am using Windows XP Home SP 3
    Problem program named dice3.c

    include <stdio.h>

    include <stdlib.h>

    include <time.h>

    define ROLLS 1000

    int dice1(int d1);
    int dice2(int d2);

    int main()
    {
    int d1,d2,total,loop,n;
    int cnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0,cnt6=0,cnt7=0,cnt8=0,cnt9=0,cnt10=0;
    int running_total=0;
    float average;
    int countd1,countd2;

    srand((unsigned)time(NULL));
    for(loop=1;loop&lt;ROLLS;loop++)
    {
    d1=rand() %6 + 1;
    
    d2=rand() %6 + 1;
    
    total=d1 +d2;
    dice1(d1);
    dice2(d2);
    running_total +=total;
      }
    printf(&quot;You rolled %d and %d: Total %d\n&quot;,d1,d2,total);
    
    average=(float)running_total/ROLLS;
    printf(&quot;The average roll for %d rolls was %3.1f\n&quot;,ROLLS,average);
    

    printf("Number 1 = %d\n",cnt1);
    printf("Number 2 = %d\n",cnt2);
    printf("Number 3 = %d\n",cnt3);
    printf("Number 4 = %d\n",cnt4);
    printf("Number 5 = %d\n",cnt5);
    printf("Number 6 = %d\n",cnt6);
    printf("Number 7 = %d\n",cnt7);
    printf("Number 8 = %d\n",cnt8);
    printf("Number 9 = %d\n",cnt9);
    printf("Number 10 = %d\n",cnt10);

    system("pause");
    return(0);

    int dice1(int d1)
    {
    if(d1==1)
    cnt1++;
    if(d1==2)
    cnt2++;
    if(d1==3)
    cnt3++;
    if(d1==4)
    cnt4++;
    if(d1==5)
    cnt5++;
    if(d1==6)
    cnt6++;
    if(d1==7)
    cnt7++;
    if(d1==8)
    cnt8++;
    if(d1==9)
    cnt9++;
    if(d1==10)
    cnt10++;
    }

    int dice2(int d2)
    {
    if(d2==1)
    cnt1++;
    if(d2==2)
    cnt2++;
    if(d2==3)
    cnt3++;
    if(d2==4)
    cnt4++;
    if(d2==5)
    cnt5++;
    if(d2==6)
    cnt6++;
    if(d2==7)
    cnt7++;
    if(d2==8)
    cnt8++;
    if(d2==9)
    cnt9++;
    if(d2==10)
    cnt10++;
    }

    }

    Full compile log

     
    • cpns

      cpns - 2008-12-03

      > I'm a 67 year old retired guy who is just learning C primarily for the mental exercise.

      Fair enough; and admirable. A lot of what I said may have bemused you. I would not worry about it too much, to have absorbed some of it is progress, light will dawn if you persevere.

      > I moved the initialization of the cnt variable from the main() to a global
      > because I figured it would have to be declared in each function where it
      > was used otherwise so it seemed more efficient than to declare it twice.

      You misunderstand the concepts of scope and instance perhaps. If two people are called Mary, they are not the same person. Equally two local variables with the same name are not the same variable. Making cnt global, is like having one Mary in the whole school as opposed to two Marys in separate classes (kind of, this analogy is getting a bit stretched!). That is not to say that you don't actually want one cnt, but there are better ways of making it available amongst functions that making it global.

      I have been involved in projects of hundreds of thousands of lines of code, and never used a global variable.

      > I get the incrementation but not the part in brackets and how it would be used.
      array[n] access the nth element of an array (note that arrays start from zero, hence the -1, so that rolling a one increments element zero).

      > Perhaps I should skip ahead in the book and locate the section on arrays.

      In your own time perhaps. Don't be pressured by me.

      Clifford

       
    • Anonymous

      Anonymous - 2008-12-01

      Ooops. Discovered I made some errors in the post.

      Forgot to tell you the error.

      I get an error that says:

      [Linker error] undefined reference to `dice1'
      And also one for 'dice2'

      Somehow I also cut off the compiler log I had pasted into the original in Word before bringing it inot the forum.

      Arrggh. But the compiler just shows those errors and says the errors are in the function main().

      Which makes sense because that is where I tried to call the functions.

      Also, is there any way to edit a post after you submit it? I couldn't see a way.

       
    • Anonymous

      Anonymous - 2008-12-01

      Back again. Decided I better post the full contents of the compile log.

      Compiler: Default compiler
      Executing gcc.exe...
      gcc.exe "J:\Programming\Projects\C-language\middle\dice.c\dice3.c" -o "nul" -ansi -traditional-cpp -fverbose-asm -g3 -I"include" -L"lib" -g3
      C:\DOCUME~1\WILLIA~1\LOCALS~1\Temp/ccoLcaaa.o(.text+0x207): In function main': J:/Programming/Projects/C-language/middle/dice.c/dice3.c:26: undefined reference todice1'
      C:\DOCUME~1\WILLIA~1\LOCALS~1\Temp/ccoLcaaa.o(.text+0x212):J:/Programming/Projects/C-language/middle/dice.c/dice3.c:27: undefined reference to `dice2'
      collect2: ld returned 1 exit status

      Execution terminated

       
    • cpns

      cpns - 2008-12-02

      dice1() and dice2() must exist outside of main(). In C you cannot nest functions. Move the final } up to the line after return(0); in main().

      Clifford

       
    • Anonymous

      Anonymous - 2008-12-02

      Thank you thank you thank you Clifford!

      I had stared at that code until I was blind and didn't see the misplaced right bracket.

      That solved the problem but, of course then another one popped up. But it was easy to fix. I had to make some variable global instead of local in the main function.

      I knew it had to be something simple.
      But I had searched all over for info on functions and how to enter them etc. and had scoured the code letter by letter and it seemed to be perfect but kept generating errors. And the errors were wrong. There wasn't anything wrong with the function definition or its calling ... it was the darn right bracket in the wrong place.

      Oh well ... that's how we learn.

      Thanks again.

       
    • cpns

      cpns - 2008-12-02

      > I had to make some variable global instead
      > of local in the main function.

      Arrrrrggggggghhhhhhh!!!! That might be a sloution, but it is never the best solution. You may have simply replaced a bug with a poor design. I wonder what you did? See: http://www.embedded.com/columns/breakpoint/193101156?_requestid=121278 - it refers to embedded systems but only because some embedded software developers thing they are a special case, globals are never good, or necessary.

      BTW, you realise that:

      int cnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0,cnt6=0,cnt7=0,cnt8=0,cnt9=0,cnt10=0;

      would be far better coded as:

      int cnt[10] = {0} ;

      which then makes the two functions dice1() and dice2() entirely unnecessary because:

      dice1(d1);
      dice2(d2);

      can be replaces with:

      cnt[d1-1]++ ;
      cnt[d2-1]++ ;

      and you can use a loop to print out the data by iterating through teh array rather than repeated prints.

      As it happens you never needed dice2() and dice2() in any case since they are identical to each other save the differently named argument, and that makes no difference.

      dice(d1) ;
      dice(d2) ;

      would suffice (or at least be equivalent, since I am not actually sure what you are trying to do).

      The argument is passed by value, so the fact that it has the same name as the variable in the calling function does not make it the same variable!

      You also declared dice1() and dice2() to return an int but returned nothing.

      Your loop is incorrect, it performs only 999 rolls, not 1000.

      I have no idea what cnt7 to cnt10 were for since d1 and d2 always have values 1 to 6.

      I have no idea either why you have ROLLS = 1000, but then roll twice in each loop. Why not simply roll 2000 times? If you are trying to log the distribution of a pair of dice, you have it all wrong in any case. You need twelve accumulators not 10, and the accumulation is:

      cnt[d1+d2-1]++ ;

      or

      dice( d1+d2 ) ;

      if you insist on your design.

      I'd show you the simpler solution if I were entirely sure what it was you were attempting to do. (unless this is your homework assignment).

      Clifford.

       
    • Anonymous

      Anonymous - 2008-12-03

      I checked out the link on global variables. I get the message that globals are ungood :)

      Much of that was way beyond me. But some I understood.

      I'm a 67 year old retired guy who is just learning C primarily for the mental exercise. There is something I would like to do if I ever learned enough but it isn't the prime motivator.

      I'm not in school so it isn't exactly " homework ". I'm on page 210 of the 666 page Dummies book which, I'm sure, is just a basic introduction into C.

      I was doing an execise in the book and I was curious how many times each number would come up so I attempted to find out. I knew there were undoubtedly better ways to do it, but I haven't learned them yet.

      The better ways to do things that you showed me I haven't come across in the book yet and don't understand how they work and are used. Hopefully they will be explained as I get further into the book.

      I do understand many of the things you indicated I did wrong such as declaring the functions to return an int and then didn't have them return anything. I screwed up royally several places.

      I moved the initialization of the cnt variable from the main() to a global because I figured it would have to be declared in each function where it was used otherwise so it seemed more efficient than to declare it twice.

      You said I could do:

      int cnt(10) = {0};

      I'm not sure but I 'think' that defines an array and initializes it to zero.

      Then you said I could replace the

      dice1(d1);
      dice1(d2);

      with

      cnt[d1-1]++;
      cnt[d2-1]++;

      which I don't understand. I get the incrementation but not the part in brackets and how it would be used.

      Hmmm.

      Perhaps I should skip ahead in the book and locate the section on arrays.

      I really appreciate you taking the time to show me my mistake(s). It is extremely helpful.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.