inlining callbacks question
Christopher Layne
clayne@anodized.com
Sun Feb 11 14:02:00 GMT 2007
Given this simple toy code:
/* */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct cbt__ cbt;
typedef void (*cbt_cb_display)(cbt *);
struct cbt__ {
char *text;
cbt_cb_display display;
};
static void cbt_display(cbt *c)
{
fprintf(stdout, "c->text == %s\n", c->text);
return;
}
extern cbt *cbt_new(void)
{
cbt *c;
c = malloc(sizeof *c);
c->text = NULL;
c->display = cbt_display;
return c;
}
int main(int argc, char **argv)
{
cbt *c;
if (argc <= 1) return EXIT_FAILURE;
c = cbt_new();
c->text = argv[1];
#ifdef CB
c->display(c);
#else
cbt_display(c);
#endif
return 0;
}
/* */
I notice that it seems impossible to get that callback to ever be inlined.
$ gcc -DCB -W -Wall -pedantic -O2 -S -o /dev/stdout cb.c
[...]
movl %eax, (%esp)
call *4(%eax)
xorl %eax, %eax
[...]
$ gcc -DCB -W -Wall -pedantic -O3 -S -o /dev/stdout cb.c
[...]
movl %eax, (%esp)
call cbt_display
xorl %eax, %eax
[...]
Okay, better.. but remove all use of the callback and call directly:
$ gcc -W -Wall -pedantic -O3 -S -o /dev/stdout cb.c
[...]
movl %edx, 8(%esp)
movl $.LC0, %edx
movl %edx, 4(%esp)
movl stdout, %eax
movl %eax, (%esp)
call fprintf
xorl %eax, %eax
[...]
Is it impossible for gcc to inline this? It should seem doable considering
that the callback function is directly accessible to the compiler and even
within the same module. Is the issue related to the fact that the function
pointer is not read-only? If so, I would expect it to always result in:
call *4(%eax)
But since I do see it calls the function directly, I'm wondering if there is
a way to inline these simple callbacks. I don't exactly know how to get the
function pointer to be const and assign to it within cbt_new(), other then
using a statically defined default and memcpy(c, &cbt_default, sizeof *c).
But this seems hardly portable, and it also doesn't result in anything
useful as far as the goal.
-cl
More information about the Gcc-help
mailing list