[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: C++ religious war (was: llua Higher-level C API for Lua)
- From: Sean Conner <sean@...>
- Date: Sat, 22 Mar 2014 22:35:32 -0400
It was thus said that the Great William Ahern once stated:
>
> I think the issue with C's heritage is overblown, especially considering
> that modern compilers support pre-compiled headers. The data structure
> definitions that must be parsed from header files would also have to be
> parsed and loaded from binary formats, and the speed benefits aren't really
> that astounding. I think the greater problem is the practice of people
> having dozens or even hundreds of compilation units. In many projects every
> little C or C++ file has like 2 or 3 functions defined. Far fewer people do
> stupid stuff like that in Java, C#, or other languages.
I've been playing around with linking recently. For an experiment, I took
a program I wrote [1], and a library it uses [2], placed all the code into
one large file, and compiled it. It made some difference in the executable
size (a bit smaller). Knowing that some compilers will inline static
functions, the second experiment I marked every function as static (except
for main(), which had to remain globally visible).
First off, there were quite a few functions that were not used (mostly
from the library), and second, a larger number of functions simply
disappeared as they were inlined. I think I counted something like 25
functions were either no used, or inlined. And the executable size was a
bit more noticeable this time.
Now, I know that when code is compiled into a library, only the bits that
are actually referenced are included into the final executable, but I found
out there's a bit more to it than that. For the library in question, it
contains the following:
text data bss dec hex filename
1197 0 0 1197 4ad nodelist.o (ex libcgi6.a)
1659 0 0 1659 67b util.o (ex libcgi6.a)
1536 0 0 1536 600 pair.o (ex libcgi6.a)
4136 0 0 4136 1028 cgi.o (ex libcgi6.a)
1636 0 0 1636 664 rfc822.o (ex libcgi6.a)
4326 0 0 4326 10e6 htmltok.o (ex libcgi6.a)
812 0 0 812 32c mail.o (ex libcgi6.a)
1736 0 0 1736 6c8 chunk.o (ex libcgi6.a)
341 0 0 341 155 bisearch.o (ex libcgi6.a)
4235 0 8736 12971 32ab crashreport.o (ex libcgi6.a)
1484 0 0 1484 5cc url.url.o (ex libcgi6.a)
2050 0 0 2050 802 url.http.o (ex libcgi6.a)
909 0 0 909 38d url.file.o (ex libcgi6.a)
Now, if I were to use RFC822HeadersRead() (from rfc822.o), not only it
include the object code for RFC822LineRead() (since RFC822HeadersRead() uses
that), but also two other functions I don't use. What's happening is that
the linker [3] is including all of rfc822.o even though I don't use all of
it. To ensure that the exectable only includes those functions used out of
a library, you have to basically put each public routine in its own object
file, which could explain the "lots of small files" you might see in C or
C++.
-spc
[1] https://github.com/spc476/mod_blog
[2] https://github.com/spc476/CGILib
[3] I'm using an older GCC development chain. It is possible that what
I'm describing has changed since the version I'm using was written.
- References:
- Re: C++ religious war (was: llua Higher-level C API for Lua), steve donovan
- Re: C++ religious war (was: llua Higher-level C API for Lua), Roberto Ierusalimschy
- Re: C++ religious war (was: llua Higher-level C API for Lua), Hisham
- Re: C++ religious war (was: llua Higher-level C API for Lua), steve donovan
- Re: C++ religious war (was: llua Higher-level C API for Lua), Roberto Ierusalimschy
- Re: C++ religious war (was: llua Higher-level C API for Lua), Jeremy Ong
- Re: C++ religious war (was: llua Higher-level C API for Lua), Hisham
- Re: C++ religious war (was: llua Higher-level C API for Lua), Coroutines
- Re: C++ religious war (was: llua Higher-level C API for Lua), steve donovan
- Re: C++ religious war (was: llua Higher-level C API for Lua), William Ahern