From: David Laight > Sent: 07 August 2023 09:40 .... > with (retyped so it may be wrong): > #define is_constexpr(x) sizeof(*(0 ? (void *)((long)(x) * 0) : (int *)0)) == 1) Bah, I know why that works and I still got is backwards :-( Basically the compiler needs to find a type that is 'compatible' with both the possible results. Since '(void *)0' is a valid 'int *' value that gives 'int *'. But '(void *)(anything_else)' requires the 'int *' be converted to 'void *'. Also the following seems to compile to sane code for all types on 32bit and 64bit x86. int errno; #define MAXERRNO 0x4000 #define type int * type sysret(type arg) { if ((unsigned long)arg < 0ul - MAXERRNO) return arg; errno = -(long)arg; return (__typeof(arg))-1; } You do get a comparison but no sign extensions. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)