SDCC : pic16/pic14 2.6.1 #4490 (Nov 28 2006) (UNIX)
It appears that printf with two %hd parameters fail:
printf("hd-Test: %uhd %uhd", c1, c2);
In this case, the first parameter is printed correctly, but the second parameter is printed as if it was a 0 value.
minimal exampleSDCC : pic16/pic14 2.6.1 #4490 (Nov 28 2006) (UNIX)
Logged In: YES
user_id=770505
Originator: NO
What is your stack size? Try increasing it to
256 bytes (the maximum for small memory model programs)
regards,
Vangelis
Logged In: YES
user_id=145718
Originator: YES
My stack size was 200 bytes. I've tried increasing it to 256 bytes without this affecting the result.
Note that printing int parameters using printf("%ud %ud"...) work fine. Even automatic casting from char parameters to int works, just not specifying %hd for more than one parameter.
I experience the same behavior with printf_small() and printf_tiny().
Logged In: YES
user_id=1115835
Originator: NO
This bug is caused by SDCC casting char varargs to int at the caller; the second %uhd accessed the high-byte of the upcast c1, which was always 0x00 since c1 was never negative (I guess).
The workaround is not to use char arguments in vararg functions; the current fix is to grab ints instead of chars in vfprintf, printf_small, and printf_tiny.
"Fix" implemented in SDCC 2.6.2, r4511. Please report if this did not fix your problem.
... and be careful when using char sized arguments in own vararg functions---these will always come disguised as ints. This behaviour is documented in the manual, though I do not to what extend, my LyX is not yet functional ;-).
Regards,
Raphael
Logged In: YES
user_id=589052
Originator: NO
Hi,
SDCC can also push a char instead of int.
The 3rd printf in code snippet below
pushes the char argument as char.
So there is a need for a "byte popping"
output format for printf.
Unfortunately "%b" is used by printf (PIC16)
to output in binary (base 2) whereas
printf (8051) would use 'b' to denote a
length modifier that reads a char value
from the stack.
Also unfortunately the use of %h (before you
changed it) was not standard conformant either.
Now it is correct but won't help if the
argument is specified as (char)something.
Maybe there's a standard (or a proposed
standard) for this needed functionality?
I found nothing in:
http://www.open-std.org/jtc1/sc22/wg14/
which might or might not be the correct
address to look?
Greetings,
Frieder
-----8<---------------------------
#include <stdio.h>
unsigned char c = 0xab;
int i = 0xabcd;
void main(void)
{
printf(" %02x",c);
printf(" %02x",(int)c);
/* this one pushes as char on SDCC
(for sdcc -mpic16 as well)
The length modifier 'b' is non-standard
(but implemented for printf on 8051). */
printf(" %02bx",(char)c);
/* "hh" is defined in C standard 7.19.6.1
but not implemented for 8051.
(It would expect c pushed as an int
so would probably be of much use anyway).
Better not have this resource hog:^) */
printf(" %02hhx",c);
printf(" %02hhx",i);
printf("\r\n");
}
Logged In: YES
user_id=1115835
Originator: NO
Hi Frieder,
your solution only works if c is originally defined as 'unsigned something'.
void foo(char c) {
printf("%uhd", (char)c); // format string does not matter
}
still casts (char)c to int. Rather strange behaviour to my eyes...
Same behaviour occurs if you change 'unsigned char c = 0xab;' to 'char c = 0xab;' in your example.
Any ideas? Should this be considered a bug in the iCode generator?!?
Reopening this one to indicate new problems; code now fails with passing unsigned c via '(char)c'.
Still wondering,
Raphael