In the external code that I am using there is enum:
enum En {VALUE_A, VALUE_B, VALUE_C};
In another external code that I am using there ar
Converting enum-to-int, e.g. int(VALUE_A), happens automatically/transparently.
Converting int-to-enum, e.g. En(ValA), can benefit from sanity checking to make sure the int value is a valid member of the enum. (Though hopefully the library code doesn't assume its enum values are valid in the first place.)
While it won't help with "int x" cases, you can help somewhat by changing:
#define ValA 5
To:
#define ValA VALUE_A
Provided enum En() is included/defined everywhere, both ValA and VALUE_A will work for both foo(int) and bar(En) everywhere automatically/transparently.
You could use:
#ifdef ValA
STATIC_ASSERT( ValA == VALUE_A, ValA_equal_VALUE_A );
#undef ValA
#else
#warning "ValA undefined. Defining as VALUE_A"
#endif
#define ValA VALUE_A
Where STATIC_ASSERT is something like:
/* Use CONCATENATE_4_AGAIN to expand the arguments to CONCATENATE_4 */
#define CONCATENATE_4( a,b,c,d) CONCATENATE_4_AGAIN(a,b,c,d)
#define CONCATENATE_4_AGAIN(a,b,c,d) a ## b ## c ## d
/* Creates a typedef that's legal/illegal depending on EXPRESSION. *
* Note that IDENTIFIER_TEXT is limited to "[a-zA-Z0-9_]*". *
* (This may be replaced by static_assert() in future revisions of C++.) */
#define STATIC_ASSERT( EXPRESSION, IDENTIFIER_TEXT) \
typedef char CONCATENATE_4( static_assert____, IDENTIFIER_TEXT, \
____failed_at_line____, __LINE__ ) \
[ (EXPRESSION) ? 1 : -1 ]