Wish: __builtin_side_effect_free_p, __builtin_lvalue_p

Niels Möller nisse@lysator.liu.se
Wed Feb 21 02:49:00 GMT 2001


Consider the following problem:

I have a macro

  #define FOO(f, a) ((f)->foo((f), (a)))

It evaluates its first argument twice (and I see no easy way to fix
that). However, that's no big problem, because usually the macro is
used like

  FOO(o, something), FOO(o->other, something)  (i)

where evaluating the first argument has no side effects. But
occasionally, I make a mistake and use something more complex as the
first argument, like

  FOO(make_object(some_operation_with_sideeffects), something)

and that breaks. I'd like to be able rewrite the macro so that those
errors are detected at compile time. I have tried

  #define FOO(f, a) ( (void)&(f), ((f)->foo((f), (a)))) (ii)

which kind-of solves the problem: It causes a compile time error for
(ii). The construction (void)&(f) is a test for the lvalue-ness of f.
(But with some compile-time sideeffects: if the argument is a
variable, the compiler can't allocate it to a register).

And lvalue-ness is not quite the right test either, For instance
FOO(*p++, something) would pass the test, and I'd like to have it
raise an error as well.

There's the __builtin_constant_p construction, perhaps one could add
analogous tests __builtin_lvalue_p (to test lvalue-ness) and
__builtin_side_effect_free_p (to test if evaluating an expression can
have side effects).

Given a __builtin_side_effect_free_p, I would also like to provoke a
compile time warning or error if it returns false. I'm not sure how to
do that either, a compile-time analogue to assert() might be useful.

Best regards,
/Niels



More information about the Gcc-bugs mailing list