D - Re: Can we have context functions?
- Nic Tiger (80/80) Mar 15 2003 Hi Walter,
Hi Walter, Recently I thought a lot of concept which would provide support for logging and tracking without Cish macroses. This thoughts led me to the notion of context functions. DEFINITION. Context function is a function which accepts along with it's own parameters several hidden parameters such as FILE, LINE or FUNC. This hidden parameters are always passed when the function is called and have values describing the place where call is originated. Let's suppose that __context keyword enables us to define context function, and __file, __line, __func are keywords that designate hidden parameters inside context function. Now let's look at concepts of using logging and tracking in C and D. 1. Logging - the method to store some information along with description of it's sourse ============ C #define LogStr(str) DoWriteLogStr ( "%s,%d: %s\n", __FILE__, __LINE__, str ) ... main () { LogStr ("got here" ); ... LogStr ("got here" ); } ============ D __context void LogStr ( char[] str ) { printf ( "%.*s,%d: %.*s\n", __file, __line, str ); } ... main () { LogStr ("got here" ); ... LogStr ("got here" ); } 2. Tracking - the method to determine who called particular function ============ C #define _malloc(s) malloc_tracked (s, __FILE__, __LINE__) void *malloc_tracked ( size_t size, char *file, int line ) { printf ("malloc(%d) from %s,%d\n", size, file, line ); return malloc ( size ); } main () { void *p = _malloc ( 10 ); } ============ D __context void *malloc ( size_t size ) { printf ("malloc(%d) from %s,%d\n", size, __file, __line ); // do allocation here... } main() { void *p = malloc ( 10 ); } ========================== end of examples Note that in D we not only got rid of preprocessor usage and have the identical behavior, but also eliminated intermediate function malloc_tracked in the second example. As I see the implementation for this concept is trivial - pass context parameters to function just like you pass object pointer to class methods. The keywords used bear imagination. I don't think that names __context and others are perfect, but they are relevant to problem being solved. Another issue is that we need support via version statement in order to find out whether current function is context or not. Then we could rewrite the second example as: /*__context*/ void *malloc ( size_t size ) { version(__context) { printf ("malloc(%d) from %s,%d\n", size, __file, __line ); } // do allocation here... } And now we can turn functions into context functions and vice versa easily. I would like you to consider the examples given and say your word about it. Any critique and afterthought are welcome. Nic Tiger.
Mar 15 2003