I'm designing an application and came across an implementation issue. I have the following struct definition:
app.h
:
struct application_t{
void (*run_application)(struct application_t*);
void (*stop_application)(struct application_t*);
}
struct application_t* create();
The problem came when I tried to "implement" this application_t
. I tend to define another struct:
app.c
:
struct tcp_application_impl_t{
void (*run_application)(struct application_t*);
void (*stop_application)(struct application_t*);
int client_fd;
int socket_fd;
}
struct application_t* create(){
struct tcp_application_impl_t * app_ptr = malloc(sizeof(struct tcp_application_impl_t));
//do init
return (struct application_t*) app_ptr;
}
So if I use this as follows:
#include "app.h"
int main(){
struct application_t *app_ptr = create();
(app_ptr -> run_application)(app_ptr); //Is this behavior well-defined?
(app_ptr -> stop_application)(app_ptr); //Is this behavior well-defined?
}
The problem confusing me is if I this calling to (app_ptr -> run_application)(app_ptr);
yeilds UB.
The "static type" of app_ptr if struct application_t*
, but the "dynamic type" is struct tcp_application_impl_t*
. The struct application_t
and struct tcp_application_t
are not compatible by N1570 6.2.7(p1):
there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types
which obviously is not true in this case.
Can you please provide a reference to the Standard explaining the behavior?