Click here to Skip to main content
15,881,757 members
Articles / Programming Languages / C++
Tip/Trick

Some Handy Visual C++ Pre-Processor Macros

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
10 Apr 2012CPOL2 min read 30.9K   17   13
C/C++ pre-processor macros which I have found to be quite useful, so I decided to share them. I hope they help you as much as they've helped me.

Over the last few years, I’ve been writing a lot of C++ that I’ve targeted for multiple platforms and/or multiple compilers. It has always been somewhat of a delicate task to make C++ code portable, especially when starting with Visual Studio and targeting other platforms like Linux using GCC.

Along with multi-target compilations, C++ pre-processor macros can be a useful tool in reducing the amount of mundane, rather simple, and rudimentary code that many C++ programmers find themselves writing. Here’s a few macros that I’ve used to ease my own development pain, I hope someone else can find them as handy as I have.

Please, by all means if I am incorrect somewhere please correct me. Also, if you wish to add to this list, feel free to do so.

Cross-Compilation Helpers

First up, one of the more common tasks, especially when writing libraries versus executable programs, is exporting symbols. The process to export symbols is different for the various compilers. The following should take care of GCC and MSVC:

C++
#if defined(_MSC_VER)
#  define LIB_EXPORT __declspec(dllexport)
#  define LIB_IMPORT __declspec(dllimport)
#elif defined(__GNUC__)
#  define LIB_EXPORT /* */
#  define LIB_IMPORT extern
#endif
#
#if defined(__cplusplus)
#  define EXTERN_C extern "C"
#else
#  define EXTERN_C /* */
#endif

Use the EXTERN_C macro when name-mangling on exported functions must be avoided. 

There are many ways to tackle symbol exports. In fact if I’m not mistaken, GCC now has synonyms for __declspec(dllexport/dllimport) so there may not even be a need to use the pre-processor to first establish which compiler is in use for the import/export macros mentioned above. It all depends on which version of GCC you’re using.

Calling Convention Helpers

Most, if not all compilers assume a calling convention when a function is not decorated with one. When problems arise with mis-matched calling conventions (almost always with exported functions) then use the following macros to specify a calling convention rather than leaving it up to the compiler. 

C++
#if defined(_MSC_VER)
#  define STDCALL __stdcall
#  define CDECL __cdecl
#  define FASTCALL __fastcall
#elif defined(__GNUC__)
#  define STDCALL  __attribute__((stdcall))
#  define CDECL /* */
#  define FASTCALL __attribute__((fastcall))
#endif 

Function Inlining 

Compilers will often attempt to make functions inline where it makes sense to do so (depending on compiler flags, etc.). If you wish to force the compiler to make a function inline, use the following macro: 

C++
#if defined(_MSC_VER)
#  define FORCEINLINE __forceinline
#elif defined(__GNUC__)
#  define FORCEINLINE inline
#endif 

Struct Member Alignment

Another possible area of compatibility mismatch is with member alignment. To force the compiler to use a specific member alignment byte-boundary, use the following macro: 

C++
#if defined(_MSC_VER)
#  define DECL_ALIGN(x) __declspec(align(x))
#elif defined(__GNUC__)
#  define DECL_ALIGN(x) __attribute((aligned(x)))
#endif

Utility Macros

I’ll end this post with some utility macros that I find to be pretty helpful…

Inline-Square 

C++
#if !defined(sqr)
#  define sqr(x) ((x)*(x))
#endif

Min/Max

C++
#if defined(min)
#  undef min
#  define min(a, b)	(((a)<(b))?(a):(b))
#endif
#if defined(max)
#  undef max
#  define max(a,b)	(((a)>(b))?(a):(b))
#endif  

Class Declarations (my personal favorite)

C++
#define DECLARE_CLASS_NOBASE(className) typedef className ThisClass
#define DECLARE_CLASS(className, baseClass) typedef baseClass BaseClass;\
DECLARE_CLASS_NOBASE(className) 

You can get rather creative with the above macro. I use it for a redumentary form of reflection or for logging purposes by converting the class name to a string that can be evaluated at run-time.

Example:

C++
#define DECLARE_CLASS_NOBASE(className) typedef className ThisClass;\
virtual const char * ThisClassName() const { return #className; }
#define DECLARE_CLASS(className, baseClass) typedef baseClass BaseClass;\
virtual const char * BaseClassName() const { return #baseClass; }\
DECLARE_CLASS_NOBASE(className)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I'm an interactive software and web developer by day and a video game developer by night. I hold an Associate's degree in Computer Information Systems, a Bachelor's degree in Game and Simulation Programming, and have been writing various types of software since 1999.

The programming languages in which I am experienced include C, C++, C#, PHP, and JavaScript--just to name a few. I have experience in creating mobile, embedded, desktop, command-line/console, web, and video game applications for consumer, business, and government/defense purposes.

Comments and Discussions

 
Questionc# Pin
Member 879290116-Apr-12 22:50
Member 879290116-Apr-12 22:50 
QuestionI'm little confused Pin
codevisio10-Apr-12 9:52
codevisio10-Apr-12 9:52 
Questionmin/max Pin
Ajay Vijayvargiya10-Apr-12 5:37
Ajay Vijayvargiya10-Apr-12 5:37 
AnswerRe: min/max Pin
Cale Dunlap10-Apr-12 7:04
Cale Dunlap10-Apr-12 7:04 
GeneralRe: min/max Pin
Ajay Vijayvargiya10-Apr-12 7:40
Ajay Vijayvargiya10-Apr-12 7:40 
GeneralRe: min/max Pin
steveb16-Apr-12 8:22
mvesteveb16-Apr-12 8:22 
GeneralRe: min/max Pin
Ajay Vijayvargiya16-Apr-12 16:45
Ajay Vijayvargiya16-Apr-12 16:45 
GeneralRe: min/max Pin
Ajay Vijayvargiya10-Apr-12 7:42
Ajay Vijayvargiya10-Apr-12 7:42 
This definition is even worse. It creates another copy, and demands copy constructor. Also the result will go nowhere.

Have you actually done some macro programing? D'Oh! | :doh:
GeneralRe: min/max Pin
Cale Dunlap10-Apr-12 8:23
Cale Dunlap10-Apr-12 8:23 
GeneralRe: min/max Pin
Ajay Vijayvargiya10-Apr-12 8:42
Ajay Vijayvargiya10-Apr-12 8:42 
GeneralRe: min/max Pin
Selvin10-Apr-12 21:20
Selvin10-Apr-12 21:20 
QuestionYou have missed some Pin
Lakamraju Raghuram9-Apr-12 23:57
Lakamraju Raghuram9-Apr-12 23:57 
AnswerRe: You have missed some Pin
Cale Dunlap10-Apr-12 7:12
Cale Dunlap10-Apr-12 7:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.