(for C++) my current clear macro in VS2010 is:
#define CLEAR(v) do { __pragma(warning(suppress: 4127 4836)) typedef std::remove_reference< decltype(v)>::type T; static_assert( std::is_pod<T>::value || (__has_trivial_constructor(T) && __has_trivial_destructor(T)), "must not CLEAR a non-POD!" ); static_assert( !std::is_pointer<T>::value, "pointer passed to CLEAR!" ); memset(&(v), 0, sizeof(v)); } while(0)
You can make up your variant using stuff in type_traits header.
A formatted verision with explanations:
#define CLEAR(v) \
do { \
__pragma(warning(suppress: 4127 4836)) \
typedef std::remove_reference< decltype(v)>::type T; \
static_assert( \
std::is_pod<T>::value \
|| (__has_trivial_constructor(T) && __has_trivial_destructor(T)), \
"must not CLEAR a non-POD!" ); \
static_assert( !std::is_pointer<T>::value, "pointer passed to CLEAR!" ); \
memset(&(v), 0, sizeof(v)); \
} while(0)
outer do-while to make it usable like a genuine function in all places including if/else.
Remove_reference is needed so it works with lvalues, decltype alone makes int* and int*& different and is_pointer reports false for the latter.
The is_pod check is good for general, the additional condition allows struct A1 : A; case work where A is POD and A1 adds only more POD members. For is_pod purpose it's false, but to clear it makes the same sense.
is_pointer check guards the expected mistype when you get the indirection wrong on pointer or pass an address of struct in confusion. Use = NULL to clear a pointer please. ;-)
The __pragma
is there to suppress L4 warnings that are issued otherwise.