The below code fails to compile in sdcc but compiles in gcc.
/// GPL 2.0 or later
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef struct { unsigned char x; unsigned char y; } maths_point_u8;
typedef struct { int x; int y; } maths_point_i8;
// Doesn't compile
inline maths_point_u8 *PositionToTile( const maths_point_i8 *position, maths_point_u8 *screen ) {
*screen = (maths_point_u8){ position->x * 2, position->y * 2 };
return screen;
}
// Compiles
maths_point_u8 *PositionToTile_global( const maths_point_i8 *position, maths_point_u8 *screen ) {
*screen = (maths_point_u8){ position->x * 2, position->y * 2 };
return screen;
}
void main() {
maths_point_i8 position = { 1, 2 };
maths_point_u8 screen;
PositionToTile( &position, &screen );
printf( "Start\n" );
printf( "End\n" );
}
#ifdef __SDCC
__sfr __at 0xff sif;
int putchar( int c ) {
sif = 'p';
sif = c;
return c;
}
#endif
// sdcc -mz80 --fverbose-asm ./inline_struct_cast.c -o inline_struct_cast.ihx
$ sdcc -mz80 --fverbose-asm ./inline_struct_cast.c -c ; echo $?
./inline_struct_cast.c:25: warning 283: function declarator with no prototype
./inline_struct_cast.c:12: error 20: Undefined identifier 'position'
./inline_struct_cast.c:12: error 27: Pointer required
./inline_struct_cast.c:12: error 47: indirections to different types assignment
from type 'void'
to type 'unsigned-char data'
from type 'void'
to type 'unsigned-char data'
1
$ gcc ./inline_struct_cast.c -c ; echo $?
0
$ sdcc -v
SDCC : z80/sm83/z80n/mos6502/mos65c02/f8 TD- 4.5.2 #15530 (Linux)
The workaround, until the fix, is to introduce a temporary:
The generated inline code looks good then:
Edit: Taking a look again, the code is actually not as efficient as it could be. The full expansion of both lines is:
where the whole second part is all for just the two bytes, the address of which could have been known immediately and also accessible via IX in this case. So the most effective way to write PositionToTile (and also a workaround) is still just:
which, when inlined, produces much less code:
and, of course, even better code is generated if the position and screen are global:
Last edit: Janko Stamenović 2025-07-30