简体   繁体   中英

How to use C macro's (#define) to alter calls but not prototypes

Older code in our application contains calls to malloc , realloc and free . With our updated code, our own implementations are called instead of the standard runtime ones. Examples are shown below,

#define malloc(s) OurMalloc(s)
#define free(p)   OurFree(p)

This works fine for the updated code and for the newer C++ code we simply implement global new and delete operators, so the C++ solution is 'cleaner'.

The problem is that we now have to include a 3rd party library, which has classes that contain methods that have names like malloc and free , eg

   class ABC
   {
      public:
      ...
      void free (char *p);
   };

If the free method of the class has the same number of arguments, the C/C++ preprocessor simply replaces all occurrences of free by ourFree , even in the class definition, even when calling the method free of the class ABC . So the class definition above and the following call:

ABC abc;
abc.free(p);

are replaced by,

class ABC
   {
   public:
      ...
      void OurFree (char *p);
   };

ABC abc;
abc.OurFree(p);

Which may compile, but which doesn't link of course.

If ABC::free has a different number of arguments than the standard free, the compiler still gives a warning. we would like to avoid them.

Some alternative solutions are:

  • undefining our defines in the beginning of the 3rd party include file and redefining it later
  • make sure that the 3rd party include file is always included before our own define's

But even then, if our code is required to call these malloc or free methods of the 3rd party classes, the preprocessor will still alter the calls, unless we write all calls like this:

(abc::free)(p)

Is there a way to tell a C/C++ preprocessor define that?

  • only pure C-calls must be replaced
  • prototypes MUST NOT be replaced
  • methods in classes MUST NOT be replaced

How about only defining those replacements for C and not C++:

#ifndef __cplusplus
#  define malloc(s) OurMalloc(s)
#  define free(p)   OurFree(p)
#endif

Why don't you just define your own malloc and free functions instead of using macros.

So, change:

void *OutMalloc (size_t s)

to:

void *malloc (size_t s)

in the same way that you can overright operator new and delete.

I think, although I may be wrong, the linker will look in object files for symbols before looking in libraries.

Preprocessor know nothing about about scope and semantic. So short answer - no, you can't do that.

But, you can use #undef free in library modules. On other side - this will not help, if you call methods abc.free() from your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM