Messages in this thread | | | From | "Uecker, Martin" <> | Subject | Re: detecting integer constant expressions in macros | Date | Wed, 21 Mar 2018 10:22:08 +0000 |
| |
Am Mittwoch, den 21.03.2018, 10:51 +0100 schrieb Martin Uecker: > > Am Dienstag, den 20.03.2018, 17:30 -0700 schrieb Linus Torvalds: > > On Tue, Mar 20, 2018 at 5:10 PM, Uecker, Martin > > <Martin.Uecker@med.uni-goettingen.de> wrote: > > > > > But one could also use __builtin_types_compatible_p instead. > > > > That might be the right approach, even if I like how it only used > > standard C (although _disgusting_ standard C) without it apart from > > the small issue of sizeof(void) > > > > So something like > > > > #define __is_constant(a) \ > > __builtin_types_compatible_p(int *, typeof(1 ? ((void*)((a) > > * > > 0l)) : (int*)1 ) ) > > > > if I counted the parentheses right.. > > This seems to work fine on all recent compilers. Sadly, it > produces false positives on 4.4.7 and earlier when > tested on godbolt.org > > Surprisingly, the MAX macro as defined below still seems > to do the right thing with respect to avoiding the VLA > even on the old compilers. > > I am probably missing something... or there are two > compiler bugs cancelling out, or the __builting_choose_expr > changes things.
Nevermind, of course it avoids the VLA if it produces a false positive and uses the simple version. So it is unsafe to use on very old compilers.
Martin
> Martin > > My test code: > > #define ICE_P(x) (__builtin_types_compatible_p(int*, __typeof__(1 ? > ((void*)((x) * 0l)) : (int*)1))) > > #define SIMPLE_MAX(a, b) ((a) > (b) ? (a) : (b)) > #define SAFE_MAX(a, b) ({ __typeof(a) _a = (a); __typeof(b) _b = (b); > SIMPLE_MAX(_a, _b); }) > #define MAX(a, b) (__builtin_choose_expr(ICE_P(a) && ICE_P(b), > SIMPLE_MAX(a, b), SAFE_MAX(a, b))) > > > > int foo(int x) > { > int a[MAX(3, 4)]; > //int a[MAX(3, x)]; > //int a[SAFE_MAX(3, 4)]; > //return ICE_P(MAX(3, 4)); > return ICE_P(MAX(3, x)); > }
| |