code:
#include <stdio.h>
void main() {
unsigned char i = 0x5A;
unsigned char *p1 = &i, *p2 = &i;
printf("%hx %hx\n", *p1, *p2);
printf("%hx %hx\n", (unsigned char)(*p1), (unsigned char)(*p2));
printf("%hx %hx\n", i, i);
printf("%hx %hx\n", (unsigned char)i, (unsigned char)i);
printf("%hx %hx\n", (unsigned char)0x5a, (unsigned char)0x5a);
}
expected output should be:
0x5a 0x00
0x5a 0x5a
0x5a 0x00
0x5a 0x5a
0x5a 0x5a
but we get:
0x5a 0x00
0x5a 0x00
0x5a 0x00
0x5a 0x5a
0x5a 0x5a
which is somehow inconsistent.
it is not a GBDK-2020 printf() implementation bug:
;test1.c:8: printf("%hx %hx\n", (unsigned char)(*p1), (unsigned char)(*p2));
ld a, (de)
ld e, a
ld d, #0x00
ld a, (bc)
ld c, a
ld b, #0x00
push de
push bc
ld hl, #___str_0
push hl
call _printf
add sp, #6
sdcc -v:
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/gbz80/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15 4.0.7 #12016 (MINGW64)
possibly, that affects other targets.
Please provide the command line used to compile. Also check section 3.5.10 of the manual.
Philipp, i don't provide any arguments, mentioned in 3.5.10, but, as you can see, we have a "blend" of those arguments, and that is the problem. It does not follow --std-sdccxx neither --std-cxx in all cases.
with -std-cxx, i guess, output must be:
(because gbdk-2020 printf implementation expects byte on stack for %hx)
Last edit: Tony Pavlov 2021-01-27
should not
with
--std-sdcc2x(isn't that a default?) push two bytes onto stack instead of two words?ps: manual is unclear, though:
it does not say anything about default behaviour, and from that quote one might think that
--std-cxxis a default.Indeed your example should push two bytes for the non-Padauk ports. And in the test I just added, we see that doesn't work.
I stumbled across this issue recently, though in a slightly different form. It was with passing members of a struct that was a pointer.
The things below make me wonder if this issue is specific to passing dereferenced pointer values with varargs.
Context:
This produces output as if it is ignoring the casting to (uint8_t) and so every other %hd is zero instead of expected value
Interestingly the output works as expected if the data is copied into stack local vars and those are passed instead.
Similarly, changing toxa's example to use stack local or global vars instead of pointers results in the correct output.
Thanks. I can reproduce the issue. Looks like a front-end bug as apparently all non-Padauk ports are affected.
I have created a regression test, which as of [r12023] is in the test suite, but disabled.
The missing casts are already missing in the AST (see -dump-ast output), so this problem apparently happens during a very early stage in the front-end.