I came across some very interesting behavior regarding to built-in functions:
int __builtin_popcount( unsigned x ); is a gcc bult-in, which actually returns the number of 1 bits in x. int foo( unsigned x ) { return __builtin_popcount( x ); } generates a call to the __popcountsi2 function in libgcc, for any target I tried it for (well, I tried for x86, ARM and m68k). However: int (*bar( void ))( unsigned ) { return __builtin_popcount; } returns the address of the label "__builtin_popcount", which does not exist: int main( int arcg, char *argv[] ) { (void) argv; return (*bar())( argc ); } fails to compile because of an undefined reference to __builtin_popcount. The compiler does not give any warning with -Wall -Wextra -pedantic but it spits the dummy during the linking phase. The next quite interesting thing is the effect of optimisation. With -O1 or above bar() returns the address of the non-existent function __builtin_popcount() *but* main(), which dereferences bar() is optimised to simply call __popcountsi2 in the library. So the linking fails because bar() (which is not actually called by main()) refers to the nonexistent function, but if bar() is made static, the optimisiation gets rid of it and everything is fine and the linking succeeds. A further point is that the compiler generates a .globl for __popcountsi2 but it does not do that for __builtin_popcount, which is rather unusual (although not fatal, since gas treats all undefined symbols as globals). Nevertheless, gcc normally pedanticly emits a .globl for every global symbol it generates or refers to, but not in this case. At least the 4.5.x compiler behaves like that. The info page does not say that one can not take the address of a built-in function (and the compiler does not issue a warning on it), so a link time failure, which depends on whether the optimiser could eliminate the need to the actual function pointer or not, is somewhat surprising. I understand that there are very special built-in functions, some that work only at compile time, some show very funky argument handling behaviour and so on. However, many are (well, seem to be) stock standard functions, realised either as a call to libgcc or as a few machine instructions, that is, behaving like inline asm() wrapped in a static inline. Those functions, I think, should really behave like ordinary (possibly static inline asm) functions. Or, if not, at least one should be warned. I believe that the above is an issue, but I don't know if it is bug or a feature, i.e. a compiler or a documentation issue? Thanks, Zoltan