Multiple Definition Error - C. Strange problem

Discussion in 'Programmer's Corner' started by danielb33, Mar 17, 2013.

  1. danielb33

    Thread Starter Member

    Aug 20, 2012
    105
    0
    I am using writing code on a STM32F1 series micro in C.

    Every things has worked great including usb serial communication (virtual com port).

    I recently added some code to insert a decimal (we are not using any floating point numbers with the code) into a few numbers that will always have the same format - very simple.
    The code below just inserts a decimal into the array.

    I am using the standard _IO_putchar() function to send characters serially via printf().

    When writing the code shown below, I get the error message "multiple definitions of _IO_putchar. Whats the deal? Even if I delete the function name, and simply paste the code into my main loop I still get the error. Any ideas?

    void print_decV(void)
    {
    uint8_t counter, length, decimal_place = 0;

    for(counter; counter < 5; counter++)
    {
    if(int_to_char[counter] != 0)
    length = counter;
    if(int_to_char[counter] == '.')
    decimal_place = counter;
    }

    counter = 0;

    if(length == 0)
    printf("0");
    else
    {
    for(counter; counter <= length; counter++)
    {
    if(counter == decimal_place)
    printf(".");
    else
    printf("%i", int_to_char[counter]);
    }
    }

    return;
    }
     
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    I am not seeing _IO_putchar anywhere in your code. It is probably coming from a rentrant header file and / or one of those definitions above are a macro that resolves to _IO_putchar.
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    Umm, delete what function name?

    Did you "#include<stdio.h>" in your main dot c file?

    Did you have to define _IO_putchar()to direct output to your device?

    Is the dot h file protected with a #ifndef {myname} {then define my stuff once}?

    (It's been a while since I redirected the std_io and that was using a PIC, but some of the details are the same.)
     
  4. WBahn

    Moderator

    Mar 31, 2012
    17,769
    4,804
    What spinnaker and ErnieM said.

    Plus:

    I'm guessing that your "int_to_char" is a global array?

    I'm guessing that it contains the ASCII codes for the digits in your value?

    I'm guessing that it is a NUL terminated string?

    I'm guessing that all of your strings in the "int_to_char" array have four or less than four characters plus the NUL terminator?

    Is there a reason that I am having to do all this guessing about your code in order to figure out what you are trying to do?

    Here's an idea -- comment your damn code!

    Now, either the contents of the int_to_char array are ASCII codes or they are digit values. If they are digit values, then checking for the value to be 0 in the top loop to determine the length makes no sense because then if the array represented the value 10.7 you would end the loop on the second pass.

    But if they are ASCII codes, the in printing them out using the %i format specifier makes no sense because then it would print out the ASCII code value and not the character it represents.

    So it would appear to me that you are not being internally consistent in your data representation. You know, if you would comment your code then you would be far less likely to do something like that.
     
  5. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    There's also other weirdness that may be creeping into this code. Consider the first three lines of the source:

    Code ( (Unknown Language)):
    1. void print_decV(void)
    2. {
    3.     uint8_t counter, length, decimal_place = 0;
    4.  
    5.     for(counter; counter < 5; counter++)
    6.         {...
    We have a for loop that the index value (counter) is never initialized. I'm sure the OP would claim it is initialized in line 2 where it is defined, but not so. That construct only initialized the very last variable (decimal_place).

    I believe C will not initialize a local variable unless explicitly told to do so (someone correct me if this is not true), but in any case you will not bloat up and slow down your code by always explicitly initializing loop counters.

    Code ( (Unknown Language)):
    1. void print_decV(void)
    2. {
    3.     uint8_t counter, length, decimal_place = 0;
    4.  
    5.     for([B]counter = 0[/B]; counter < 5; counter++)
    6.         {...
    Is that so hard? Does it take too long to type out?
     
    Last edited: Mar 18, 2013
  6. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    I think that any normal compiler should give you a warning that the variable is uninitialized.
     
  7. WBahn

    Moderator

    Mar 31, 2012
    17,769
    4,804
    That is correct. I don't know if a compiler is even allowed to automatically initialize automatic variables (though I suspect it is since that may be the easiest way to allocate space on the stack), but it certainly isn't required to.
     
  8. danielb33

    Thread Starter Member

    Aug 20, 2012
    105
    0
    Many things I want to respond to but do not have the time lol. Thanks for the input folks
     
  9. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    So we took the time to help you yet you don't have the time to look into your own issue?
     
Loading...