This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: sizeof(function) functionality
On Tuesday 8 July 2003 7:47 am, Kristis Makris wrote:
> Interesting how you propose that. I actually came up with this last
> night:
>
> #define sizeof_function(x) ( (unsigned long) (&(endof_##x)) - (unsigned
> long) (&x))
> #define endof_function(x) void volatile endof_##x() {}
> #define DECLARE_END_OF_FUNCTION(x) void endof_##x();
>
> Note the volatile keywoard, also used when functions are declared.
Was there supposed to be a volatile keyword in the DECLARE_END_OF_FUNCTION
macro?
> It
> has the effenct of the function and its end sticking next to each
> other, or at least out of what I noticed:
What leads you to this conclusion? Do they not stick next to each other
otherwise?
> What I really want to do is have only one macro that expands into the
> above; add the volatile keyword and append the endof_function at the
> end. I'd like to add endof_function labels for a large collection of
> sources, and it feels like the compiler should be able to add those for
> me.
#define DEFINE_SIZED_FUNCTION(rtype, name, params, body) \
rtype name params body \
void endof_##name(void) { }
#define DECLARE_SIZED_FUNCTION(rtype, name, params) \
rtype name params; \
void endof_##name(void);
#define STATIC_DEFINE_SIZED_FUNCTION(rtype, name, params, body) \
static rtype name params body \
static void endof_##name(void) { }
#define STATIC_DECLARE_SIZED_FUNCTION(rtype, name, params) \
static rtype name params; \
static void endof_##name(void);
#define sizeof_function(name) ((char *)endof_##name - (char *)name)
> > Then there are more macros for locking the functions in memory, and these
> > macros merely find the difference between pointers to the two functions.
> > The purpose of this is to prevent any disk access from occurring when the
> > functions are called.
>
> While I was reading this sentence I assumed you meant the mlock() system
> call. I am afraid I don't understand how disk access came into the
> equation here.
Allegro doesn't use mlock(); it uses a DJGPP-specific function called
_go32_dpmi_lock_data(), which seems to do the same thing. If the data are not
locked in memory, they may be paged to disk; then the DPMI server will be
required to access the disk in order to read the data back in. If this
happens during the handling of an interrupt, the system is likely to crash,
since the main program may be trying to access the disk at the same time. So
all functions and data used in interrupt context must be locked in memory.
Operating systems like Windows and Linux have re-entrant disk access routines,
so it would be safe for an 'interrupt' (which would really be a concurrent
thread) to incur disk access. All the macros relating to memory locking
therefore expand to nothing on these platforms. They do actually do something
on the Mac, but I doubt that they need to - the Mac port of Allegro has
hardly been tested, used or looked at.
Sorry for the brief explanation before; I kept it brief because it wasn't
quite on topic.
> I can see sizeof_function being rewritten to -sizeof_function, or the
> absolute value, in architectures where the stack grows the other
> direction, for the portability issue.
I don't think the stack direction would make a difference. It just depends on
the order in which the functions are stored in memory, and I'd expect a
typical compiler to put functions in the order they appear in the source, if
they have the same storage class - though I wouldn't assume this of an
unknown compiler.
Ben