This is the mail archive of the gcc-help@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: 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


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