Re: Rationale behind 'extern' on protypes in .h files
On 22.12.2013 16:51, Ravi Shekhar Jethani wrote: > > Now, my real question : > 1) I cannot understand the reason behind making function prototypes as > extern. What purpose does this serve? AFAIK we put definition in a .c > file and the prototype in a .h thats it. > > 2) Why are some prototypes in some of the .h file are extern and > others are not? > > Thank you guys for reading through. Any suggestions are humbly welcome. > Ravi S. Jethani > -- > To unsubscribe from this list: send the line "unsubscribe git" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > That's an interesting question. From my understanding there is no difference for functions declarations being set to extern or not, because extern is the default on functions. It is however important for variables to mark them extern if they're in a header file. After a quick research on the web, it may be there for historical reasons. Back then, when there were one pass compilers, the compiler needed to know where the function is to be found. (extern was not default at these times?) Another reason I could make up, would be to indicate, whether the function is in the c file having the same name as the header file. For example in builtin.h there are all the functions declared extern, as the implementation of the functions are found in builtin/*.c In another header cache-tree.h there are function declarations without explicit extern keyword, and the implementation is found in the cache-tree.c file (${SAME-NAME-AS-HEADER}.C) This is however not always the case as found in archive.{c,h} I'd be also interested in knowing the real reason for this rationale. Thanks, Stefan -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Rationale behind 'extern' on protypes in .h files
Stefan Beller writes: > From my understanding there is no > difference for functions declarations being set to extern or not, > because extern is the default on functions. There is a difference for shared libraries if you would like to control which symbols are exported. With gcc, for example, you might compile using -fvisibility=hidden. Any functions explicitly declared with extern, bearing __attribute__((visibility("default")), or using visibility pragmas will be exported (similar to __declspec(dllexport) on Windows). Other functions will be internal to the shared library so you don't have to worry about callers depending on those symbols and performance can be a bit better by skipping the PLT and avoiding symbol relocations at load time. See Drepper's guide for more. http://www.akkadia.org/drepper/dsohowto.pdf pgpZa1gqS6XJz.pgp Description: PGP signature
Re: Rationale behind 'extern' on protypes in .h files
2013/12/22 Jed Brown : > There is a difference for shared libraries if you would like to control > which symbols are exported. With gcc, for example, you might compile > using -fvisibility=hidden. Any functions explicitly declared with > extern, bearing __attribute__((visibility("default")), or using > visibility pragmas will be exported (similar to __declspec(dllexport) on > Windows). Other functions will be internal to the shared library so you > don't have to worry about callers depending on those symbols and > performance can be a bit better by skipping the PLT and avoiding symbol > relocations at load time. See Drepper's guide for more. > > http://www.akkadia.org/drepper/dsohowto.pdf To check this I installed the libgit2-dev package which installed: /usr/include/git2/*.h , /usr/lib/libgit2.so Now, I exported all symbols using: $ readelf -s /usr/lib/libgit2.so and tried to match these with 'externed' prototypes in the Git source directory..no matches. I am confused!!!. Also I checked this: $ ldd git There is no 'gitish' .so in the output; it seems everything is packed inside one executable. So your second point 'skipping the PLT...' also doesn't seem to apply here. Regards, Ravi Shekhar Jethani -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Rationale behind 'extern' on protypes in .h files
Ravi Shekhar Jethani writes: > To check this I installed the libgit2-dev package which installed: > /usr/include/git2/*.h , /usr/lib/libgit2.so > Now, I exported all symbols using: > $ readelf -s /usr/lib/libgit2.so > and tried to match these with 'externed' prototypes in the Git source > directory..no matches. > I am confused!!!. libgit2 is an entirely different package from Git. If you look at the libgit2 sources (https://github.com/libgit2/libgit2), look in include/git2/common.h: /** Declare a public function exported for application use. */ #if __GNUC__ >= 4 # define GIT_EXTERN(type) extern \ __attribute__((visibility("default"))) \ type #elif defined(_MSC_VER) # define GIT_EXTERN(type) __declspec(dllexport) type #else # define GIT_EXTERN(type) extern type #endif I have always used __attribute__((visibility("default"))), but the gcc man page says extern declarations are not affected by -fvisibility, so a lot of code can be recompiled with -fvisibility=hidden with no modifications. However, this means that calls to "extern" functions with no explicit visibility use the PLT, so it is more effective to use "__attribute ((visibility))" and/or "#pragma GCC visibility" to tell the compiler which "extern" declarations should be treated as hidden. However, I don't understand what the first statement means (documentation bug?) since -fvisibility=hidden causes functions declared with 'extern' to be hidden. symbols.c: EXTERN int foo(void); int foo(void) {return 1;} $ gcc -fvisibility=hidden -DEXTERN=extern -shared -o libsymbols.so symbols.c $ nm -D libsymbols.so | grep foo $ meanwhile, $ gcc -fvisibility=hidden -DEXTERN='__attribute((visibility("default")))' -shared -o libsymbols.so symbols.c $ nm -D libsymbols.so | grep foo 055c T foo > Also I checked this: > $ ldd git > There is no 'gitish' .so in the output; it seems everything is packed > inside one executable. > So your second point 'skipping the PLT...' also doesn't seem to apply here. My comment applied to shared libraries in general, not specifically to Git (which isn't a shared library). pgpHYEPGwoA09.pgp Description: PGP signature