Nope. Function with external linkage are required to have different addresses. MSVC actually breaks this and this means that you can't reliably compare function pointers on MSVC because some different functions may happen to have same object code by chance:
void go_forward(Closure *clo, Closure *cont, Closure *forward) {
GC_CHECK(clo, cont, forward);
((Fun0)(forward->fun))(forward, cont);
}
void go_left(Closure *clo, Closure *cont, Closure *left, Closure *right) {
GC_CHECK(clo, cont, left, right);
((Fun0)(left->fun))(left, cont);
}
void go_right(Closure *clo, Closure *cont, Closure *left, Closure *right) {
GC_CHECK(clo, cont, left, right);
((Fun0)(right->fun))(right, cont);
}
GcInfo gc_info[] = {
{ .fun = (GenericFun)&go_forward, .envc = 0, .argc = 1 },
{ .fun = (GenericFun)&go_left, .envc = 0, .argc = 2 },
{ .fun = (GenericFun)&go_right, .envc = 0, .argc = 2 },
};
Since, the pointers to go_forward and go_left will be the same, the gc_info table is less useless that it could be otherwise.
But it could generate one then make the remaining three tail call to that one, or lay them out so that they are at 1byte-nop each to the next one and fallthrough the next until the last one implements the logic (This is a bit more compilcated on msvc as I believe the ABI requires a well defined prologue).