В этом решении используется прием, описанный в Обнаружение констант во время компиляции C ++ - прием использует тот факт, что целое ноль времени компиляции может быть преобразовано в указатель, и его можно использовать вместе с перегрузкой для проверки свойство «время компиляции известно».
struct chkconst {
struct Small {char a;};
struct Big: Small {char b;};
struct Temp { Temp( int x ) {} };
static Small chk2( void* ) { return Small(); }
static Big chk2( Temp ) { return Big(); }
};
#define is_const_0(X) (sizeof(chkconst::chk2(X))<sizeof(chkconst::Big))
#define is_const(X) is_const_0( int(X)-int(X) )
#define memmove_smart(dst,src,n) do { \
if (is_const(n)) {if (n>0) memmove(dst,src,n);} \
else memmove(dst,src,n); \
} while (false)
Или, в вашем случае, поскольку вы все равно хотите проверять ноль, можно использовать is_const_0 напрямую для максимальной простоты и переносимости:
#define memmove_smart(dst,src,n) if (is_const_0(n)) {} else memmove(dst,src,n)
Примечание: в данном коде используется версия is_const, более простая, чем в связанном вопросе. Это связано с тем, что Visual Studio в этом случае более соответствует стандарту, чем GCC. При нацеливании на gcc вы можете использовать следующий вариант is_const (адаптированный для обработки всех возможных интегральных значений, включая отрицательные и INT_MAX):
#define is_const_0(X) (sizeof(chkconst::chk2(X))<sizeof(chkconst::Big))
#define is_const_pos(X) is_const_0( int(X)^(int(X)&INT_MAX) )
#define is_const(X) (is_const_pos(X)|is_const_pos(-int(X))|is_const_pos(-(int(X)+1)))