[again as plain text, slightly augmented] >> It's actually part of the C standard: there may only be one definition >> of any symbol, whether that symbol refers to a function or to data. So, >> for every visible symbol X in a program, &X must be the same, no matter >> who is asking. >> All manner of things break without this. Some stuff breaks, but not much. It's pretty rare to compare the addresses of globals/functions for equality. This rule is sometimes broken on Windows, and it is rarely noticed/discussed. E.g. if you import a function but don't mark it as __declspec(dllimport), or if you "static/const-ly" take the address of a __declspec(dllimport) (gets a warning about this vary thing). windows.h uses __declspec(dllimport) pretty rigorously, so the tendency is to follow the rule. But it is easy to break. 2.c: #include <stdio.h> void CreateFileA(void); __declspec(dllimport) void CreateFileW(void); void* p = &CreateFileA; void* q = &CreateFileW; __declspec(dllexport) void MyDll() { printf("2: a:%p w:%p m:%p a2:%p w2:%p\n", &CreateFileA, &CreateFileW, MyDll, p, q); } 1.c #include <stdio.h> void CreateFileA(void); __declspec(dllimport) void CreateFileW(void); void MyDll(); void* p = &CreateFileA; void* q = &CreateFileW; int main() { MyDll(); printf("1: a:%p w:%p m:%p a2:%p w2:%p\n", &CreateFileA, &CreateFileW, MyDll, p, q); return 0; } c:\>cl -LD 2.c c:\>cl 2.lib 1.c 1.c : warning C4232: nonstandard extension used : 'q' : address of dllimport 'CreateFileW' is not static, identity not guaranteed c:\>.\1 2: a:000007FEFC338A9E w:0000000077AE2A30 m:000007FEFC331000 a2:000007FEFC338A9E w2:000007FEFC338A98 1: a:000000013F9185BE w:0000000077AE2A30 m:000000013F911050 a2:000000013F9185BE w2:000000013F9185B8 See how "w" uses the usual declaration and does meet the rule, or gets a warning, and the rest don't. __declspec(dllimport) I think of as just a nice micro optimization but I guess it is also good for a) generally making this rule more upheld b) causing a warning when the warning is also then violated. If you don't need identity, it is easy to fix the warning with a wrapper function. static void MyFoo() { foo(); } void (*pfoo) = MyFoo; /* instead of foo */ Of course, such small functions may be prone to break the rule "the other way around" under over-aggressive optimization. That is: static void MyFoo() { foo(); } static void MyBar() { foo(); } assert(&MyFoo != &MyBar); ? The Visual C++ linker also has "identical comdat" folding. template <typename T> T max(T,T); assert(&max<int> != &max<long>); ? - Jay (as well, something like LTCG/LTO could make the annotations not needed but always get the optimization/conformance "for free" (for no additional cost))