As far as I know, this is exactly the rationale, actually. Say you have:
struct a { int a;}
struct b { int b;}
struct c : a, b { };
c myc;
c* p1 = &myc;
b* pb1 = p1; // correctly points to myc's base b, which is offset
void* p2 = &myc;
b* pb2 = p2; // Would not point at instance of b, compile error
If I need void*-casting code to compile on both C and C++ compilers, I use a macro like this:
#ifdef __cplusplus
#define STATIC_CAST(T, EXPR) static_cast<T>(EXPR)
#else
#define STATIC_CAST(T, EXPR) (EXPR)
#endif
This leaves the conversion to be implicit in C, and uses the stricter static_cast in C++ to catch certain types of likely-unsafe conversions, such as the aforementioned cast from int to pointer.