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)