I believe it is due to a weak reference. The file hardware/arduino/cores/arduino/HardwareSerial.h has this declaration:
Code:
extern void serialEventRun(void) __attribute__((weak));
Note, there are two underscores before/after the attribute. For good coding practice, the 'weak' should also have two leading and two trailing underscores, since some user out there might #define weak to be 53 or some such.
And then there is the reference in hardware/arduino/cores/arduino/main.cpp:
Code:
if (serialEventRun) serialEventRun();
There are other weak references scattered through the library. HID/CDC also define a WEAK macro to simplify using the attribute.
Basically a weak reference will not pull in serialEventRun from the library if it has a reference, but if something else brings in the module that defines the function, it satisfies the link with the address. If the symbol is not pulled in, it is resolved as 0. So the line from main.cpp says if the function was pulled in, call it. If not fail the if test.
Another way to do this is to declare a pointer to a function as a common symbol (i.e. declare it in one file without a definition). If nothing else defines the variable, the linker will create a symbol in the bss area and have it initialized by 0 (presumably on an embedded board, the first thing that runs would zero out the bss area). In the module that gets pulled in with a reference would define the same variable, but initialize it with the address of a static function in the object file. Like main.cpp above, you would test the pointer before calling it (unless you have a return instruction located at location 0).
For the first case, you need to have the weak attribute, or else the compiler will delete the test, since it knows that the ISO standard mandates no object/function starts at location 0, and the if statement would never succeed.
Looking at other attributes used, I see packed in the wifi, which might be a slow down for arm (depending on whether the compiler believes it can do unaligned load/stores on ARM, it might have to do load byte/store byte to deal with packed values). There are some naked/interrupt attributes, which are presumably interrupt stuff, and would be completely different on an Arm. A few things use attribute section to get a specific section, which also might be machine dependent.
One minor coda. Weak references only work on the ELF object file format, which is pretty much the standard object file format these days for software where GCC/binutils are the primary compilers (I believe LLVM also). Some systems use other object file formats, which might not support weak references. But for Arduino, Teensy, etc. you can use weak references.