I've noticed an assembly pattern where two functions begin with different setup instructions but then branch into the same shared code. For example, one routine loads 0 into a register and another loads 1, after which both write that value to the same memory-mapped interrupt-control register and return. Can this be expressed directly in C, C++, or another higher-level language, or is it something a compiler might produce automatically when combining similar functions?
5 Answers
This is generally called a multiple-entry-point function or shared entry point. Standard C and C++ do not let one function jump directly into the middle of another function, so you normally express it structurally by putting the common operation in a helper function and passing the differing value as an argument. A compiler may later inline or merge the resulting code, but that is an implementation detail rather than something the source code directly requests.
Some older languages had explicit constructs for this. For example, older versions of Fortran supported an `ENTRY` statement for alternate entry points, but it is not considered modern or recommended practice. In mainstream C and C++, separate functions with a common helper are the usual solution.
You can imitate the layout with assembly or compiler-specific extensions, but it usually makes the control flow harder to understand and less portable. The maintainable approach is to use a shared helper. Multiple entry points were more attractive on older, tightly constrained systems where saving a few bytes mattered; today, a compiler can often perform the safe sharing automatically.
A related optimization is tail merging, where a compiler detects identical code at the ends of different control-flow paths and emits that code only once. This is common in switch statements and sometimes across functions, although cross-function merging is more specialized. It shouldn’t be confused with tail-call optimization, which is when a function ends by calling another function and returning its result directly.
For example, the high-level version would look roughly like this: `static void setInterrupts(int enabled) { MMIO_IME = enabled; }`, followed by small `EnableInterrupts` and `DisableInterrupts` wrappers that call it with 1 and 0. With optimization enabled, the wrappers may be inlined, and the compiler could arrange the machine code so the common instructions are shared. Whether it does so depends on the compiler, target architecture, optimization settings, and other constraints.

Some compiler extensions provide label addresses or computed gotos, but those are nonportable and still aren’t a normal way to jump between separate functions. They’re mainly useful for specialized low-level code.