#1248 pic16 printf with two %hd parameters fail

open
nobody
PIC16
5
2013-07-16
2006-11-28
No

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.

Discussion

  • Marius Kintel

    Marius Kintel - 2006-11-28

    minimal exampleSDCC : pic16/pic14 2.6.1 #4490 (Nov 28 2006) (UNIX)

     
  • Vangelis Rokas

    Vangelis Rokas - 2006-11-30

    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

     
  • Marius Kintel

    Marius Kintel - 2006-12-04

    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().

     
  • Raphael Neider

    Raphael Neider - 2006-12-10
    • milestone: --> 100457
    • status: open --> closed-fixed
     
  • Raphael Neider

    Raphael Neider - 2006-12-10

    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

     
  • Frieder Ferlemann

    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");
    }

     
  • Raphael Neider

    Raphael Neider - 2006-12-10

    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

     
  • Raphael Neider

    Raphael Neider - 2006-12-10
    • milestone: 100457 -->
    • status: closed-fixed --> open
     
  • Philipp Klaus Krause

    • Category: --> PIC16
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks