This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C Metaprogramming


On Tue, Jun 19, 2012 at 4:41 AM, Daniel Santos <danielfsantos@att.net> wrote:
> Yes, my topic sounds crazy huh? ?But you guys made it possible when you
> started optimizing out constant function pointers. (Thank you!!) This
> didn't mature to "full power" until 4.6.? (works in 4.6.2, not sure
> about earlier 4.6). ?Now that you can populate a struct with const
> pointers to inline functions and pass a pointer to that struct to a
> generic inline function, full C type-injection is now possible. (Well,
> you probably didn't need to be able to do it via a struct, but it sure
> cleans up the interface).
>
> Example here: http://lwn.net/Articles/500757/ (patches last sent to LKML
> on June 7th, don't have them posted elsewhere atm, sorry)
>
> However, the process of verifying that your calls by
> constant-function-pointer (much less, one that is a struct member) is
> one of examining the generated code, since __builtin_constant_p will
> always return zero when passed a function pointer (or any pointer I've
> given it thus far). ?This simple program demonstrates the problem:
>
> #include <stdio.h>
> static inline int myfunc(int a) {
> ? ?return a + 42;
> }
>
> static int (*const myptr)(int) = myfunc;
>
> int main(int argc, char *argv[]) {
> ? ?printf("is const = %d\n", __builtin_constant_p(myptr));
> ? ?/* same result if I dereference it: __builtin_constant_p(*myptr) */
> }
>
> So before filing any feature request bugs, I figured I should bring my
> discussion here first, as I believe some enhancements to gcc can better
> enable this type of programming.

The question this boils down to is - what is a constant?  The current
implementation is pretty clear (see builtins.c:fold_builtin_constant_p)
and excludes any addresses of entities (being functions or variables).
Which probably asks for a new builtin to verify this, not over-loading
__builtin_constant_p.

> First off, we need a mechanism to verify constness of a function pointer
> at build time and generate an error when the value is non-const, similar
> to the construct:
>
> #define BUILD_BUG_ON_NON_CONST(arg) ? ? ? ? ? ? ? ? ? \
> do { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ?extern void __value_non_constant(void) ? ? ? ? ? ?\
> ? ? ? ?__attribute__((error("value not constant"))); \
> ? ?if (!__builtin_constant_p(arg)) ? ? ? ? ? ? ? ? ? \
> ? ? ? ?__not_constant_error(); ? ? ? ? ? ? ? ? ? ? ? \
> } while (0)
>
> Second, it will be helpful to have a mechanism to generate a -Winline
> warning when a function call by pointer cannot be inlined. ?Obviously,
> this is impossible if you can't first determine that it's a const
> function pointer and resolve that to the actual function. ?I'm sorry to
> say that I don't have a suggestion for doing this other than some
> __builtin_isinlineable() type of function (that accepts a function
> pointer). ?Perhaps solving the above problem and assuring that, after
> this test for function pointer constness succeeds and the const function
> pointer can be resolved to an inline function, the compiler can just
> emit a warning as it would when a normal function call to an inline
> cannot be inlined. ?Here's an example:
>
> #include <stdio.h>
> static inline int myfunc(int a) {
> ? ?return a + 42;
> }
>
> static inline void jack(int (*const fnptr)(int)) {
> ? ?/* macro from above, except working for function pointers */
> ? ?BUILD_BUG_ON_NON_CONST(fnptr);
>
> ? ?/* if the above test passes, any inability to inline myfunc should
> ? ? * produce a -Winline warning
> ? ? */

I think that would be essentially the same as declaring myfunc
with attribute always-inline.  You'd get an error if the function pointer
turns into a direct call and is not inlined.

Richard.

> ? ?fnptr(0);
> }
>
> int main(int argc, char *argv[]) {
> ? ?jack(myfunc);
> }
>
> Thanks
> Daniel


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]