Multiple Definition Error - C. Strange problem

Thread Starter

danielb33

Joined Aug 20, 2012
105
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;
}
 

spinnaker

Joined Oct 29, 2009
7,835
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.
 

ErnieM

Joined Apr 24, 2011
8,179
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?
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.)
 

WBahn

Joined Mar 31, 2012
26,398
What spinnaker and ErnieM said.

Plus:

The code below just inserts a decimal into the array.

Rich (BB code):
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;
}
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.
 

ErnieM

Joined Apr 24, 2011
8,179
There's also other weirdness that may be creeping into this code. Consider the first three lines of the source:

Rich (BB code):
void print_decV(void)
{
    uint8_t counter, length, decimal_place = 0;

    for(counter; counter < 5; counter++)
        {...
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.

Rich (BB code):
void print_decV(void)
{
    uint8_t counter, length, decimal_place = 0;

    for(counter = 0; counter < 5; counter++)
        {...
Is that so hard? Does it take too long to type out?
 
Last edited:

kubeek

Joined Sep 20, 2005
5,757
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.
I think that any normal compiler should give you a warning that the variable is uninitialized.
 

WBahn

Joined Mar 31, 2012
26,398
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.
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.
 
Top