Char considered as uint8_t on device


Executing this simple code will give you a different answer on simulator (tested on macOS) and on device.

char test = -1;
pd->system->logToConsole("test = %d", test);

Simulator will give you -1, as it should. The Playdate will give you 255 as if test was an uint8_t instead of an int8_t.

In my example, using int8_t instead of char solves the issue.

This is not a sdk bug. This is just how the arm compiler defines a char. If you want it to be signed you need to do

signed char test = -1;
pd->system->logToConsole("test = %d", test);

I think you can also send in --signed_chars to the compiler as a flag, but I have not tested this

I guess my issue is not really that the playdate is using unsigned char, but the fact that a same pdx doesn't run the same way on the device and the simulator.

If it is just how the arm compiler defines a char, shouldn't I have consistency between the device and the simulator?


Yeah I agree with you, it should be the same.

As a temperery fix you can add this to your cmake file:

target_compile_options(${PLAYDATE_GAME_DEVICE} PUBLIC --signed-char)

If you have copied one of the cmake files from the sdk examples you add it after calling add_executable inside if (TOOLCHAIN STREQUAL "armgcc")

I have not done any extensive testing and as the arm docs say:

Care must be taken when mixing translation units that have been compiled with and without this option, and that share interfaces or data structures.

But you can give it a shot