C99 standard, 7.18.3p2:
— limits of ptrdiff_t
PTRDIFF_MIN −65535
PTRDIFF_MAX +65535
sdcc #7090, stdint.h:
#define PTRDIFF_MIN (-32767-1)
#define PTRDIFF_MAX (32767)
IMO, we should make ptrdiff_t the same as int_fast32_t on all targets (at least until we have support for 24-bit integers).
Philipp
I do not fully agree. IMO this small deviation is allowed, becuase we are talking about SMALL devices here where it is very unlikely one ever needs this range. Almost all supported targets have 64k address spaces (sole exception: ds390) and must turn to bankswitching to use more. But ptrdiff_t is there to contain the difference between two pointers into the SAME array (see C99 6.5.6.9) and one array cannot span multiple banks. You only need a wider range when your array contains bytes and spans more than 32k. So, I'd be more inclined to turn the mcs51 ptrdiff_t to signed int than all others to signed long.
For targets where there cannot be an object of more than 32 KB, I agree that a 16-bit ptrdiff_t (as allowed by the C90 standard) makes more sense than the 17-bit one required by C99 to C17.
Still, SDCC should be standard-compliant, and I'm trying to fix this: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2808.htm
For targets where an array of more than 32 KB could exist, we IMO should use a 24-bit ptrdiff_t, when SDCC gets support for a 24-bit signed integer type.
Looks like SDCC will have a standard-compliant ptrdiff_t for ISO C23; N2808 was voted in by WG14 (technically, WG14 could still revert that vote before C23, but I'd consider that unlikely).
While the standard allows some things for freestanding implementations that are not allowed to hosted implementations (e.g. not supporting complex types), as far as I can see, ptrdiff_t is not among them: Freestanding implemenations are required to provide stdint.h and the standard requires stdint.h to provide PTRDIFF_MIN and PTRDIFF_MAX with the stated limits.
The use of large arrays might be rare, but:
1) Someone might want to use pointer arithmetic on large array, I can see some use-cases for a 48K uint8_t array.
2) ptrdiff_t matters only for pointer subtractions, and these are rare. Even when someone does subtract pointers, AFAIK sdcc will optimize the large ptrdiff_t away if the result is assigned to a smaller integer type. Thus, IMO there is no significant penalty for being standard-compliant.
Philipp
Hi,
I don't know if we support them, but some PIC16 CPUs have >64k address spaces, such as the PIC18F47J53 I'm using right now.
Regards
We do have a larger ptrdiff_t on targets where it makes sense (e.g. ds390).
Let's close this: For C99, C11, C17 it would be too inefficient to be compliant. For C90 and C23, we are.