Click here to Skip to main content
Click here to Skip to main content

Some Handy Visual C++ Pre-Processor Macros

, 10 Apr 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
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:

#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. 

#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: 

#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: 

#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 

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

Min/Max

#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)

#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:

#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)

Share

About the Author

Cale Dunlap
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, Python, 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.
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
Questionc# PinmemberMember 879290116-Apr-12 23:50 
QuestionI'm little confused Pinmembercodevisio10-Apr-12 10:52 
Questionmin/max PinmemberAjay Vijayvargiya10-Apr-12 6:37 
This is the most absurd!
 
#  define min(a, b) (a<b?a:b)

AnswerRe: min/max PinmemberCale Dunlap10-Apr-12 8:04 
GeneralRe: min/max PinmemberAjay Vijayvargiya10-Apr-12 8:40 
GeneralRe: min/max Pinmembersteveb16-Apr-12 9:22 
GeneralRe: min/max [modified] PinmemberAjay Vijayvargiya16-Apr-12 17:45 
GeneralRe: min/max PinmemberAjay Vijayvargiya10-Apr-12 8:42 
GeneralRe: min/max PinmemberCale Dunlap10-Apr-12 9:23 
GeneralRe: min/max PinmemberAjay Vijayvargiya10-Apr-12 9:42 
GeneralRe: min/max PinmemberSelvin10-Apr-12 22:20 
QuestionYou have missed some PinmemberLakamraju Raghuram10-Apr-12 0:57 
AnswerRe: You have missed some PinmemberCale Dunlap10-Apr-12 8:12 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 10 Apr 2012
Article Copyright 2012 by Cale Dunlap
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid