Lawrence said:
How about this one <
http://www.blender.org/>, with a million lines of C
code, last I counted. Or this one <
http://dev.mysql.com/>. Or this one
<
http://www.libreoffice.org/>. Or this one <
http://httpd.apache.org/>.
So your claim is that the total number of C and C++ programs, minus
four, is less than "a lot"?
Though to be honest, I don't really see what the point is. I think
Joshua is overestimating the number of C and C++ programs that are
specific to Linux and won't build on OpenBSD or Solaris. There are
definitely some, but IME they're usually the ones that deliberately
use features peculiar to Linux, for whatever reason.
(A better argument might have been the number of C and C++ programs
that run on x86 Linux but either don't build or fail on one of the
pickier UNIXes, such as HP-UX for Itanium. But even then it's a quibble.)
What's more important is the generally poor quality of C code. (I
think much C++ is also poorly written, but arguing that is more
complicated, because it's a far larger language with more latitude for
programmer choice.)
So let's look at your examples.
Blender: Has about 260 open bugs, including memory allocation issues
and assertion failures. Much of the source is C++, which I'm not going
to look at now; but the C source is problematic. For example, there
are a few uses of strncpy. strncpy has broken semantics; it is never
the right choice. Blender also includes its own implementation of
strncpy (BLI_strncpy), for no readily apparent reason, and most of the
code uses that; but it's sub-optimal. It also uses strcpy extensively,
and I'm not convinced all of those are safe, for example in the
makesrna implementation. That's just from a minute of glancing at the
source.
MySQL: 145 bugs filed in the past 30 days, some of which are clearly
coding errors (eg #61303, #61208). I don't want to take the time right
now to prowl through the sources, but the project does not have a
great track record; see CVE-2009-2446, CVE-2006-1516 through
CVE-2006-1518, CVE-2010-3676 through CVE-2010-3683, and so on.
LibreOffice: A fork of the OOo code, which does not have a great track
record. Consider CVE-2010-3450 through -3454, etc. And while those
CVEs don't list LibreOffice among vulnerable products, the SuSE
LibreOffice update claims it's vulnerable (see [1]). I suspect the
relative lack of official vulnerability reports for LibreOffice is
because they're generally reported against OOo instead. And since LO
has significant additional features on top of the OOo base, it has a
lot more room for additional mistakes.
Apache: An outlier project, with excellent funding and a great many
eyes on the code. That hasn't kept it free of errors. Take a look at
the brand-new CVE-2011-1921, for example. Or CVE-2011-1928, a classic
error in C code, caused by a fix to the earlier CVE-2011-0419. '0419
and '1928 are only DoS vulnerabilities; but that's bad enough.
And these are extremely popular projects, so they get a lot of
attention. Less-used and less-examined code tends to be much worse.
[1]
http://secunia.com/advisories/43837/
I'll throw a few more into the mix. These are two pieces of C/C++
software that I had reason to use at work a few months. One well-known,
one not so much so.
Case A: I needed to write a web services client in C. So I went with
Axis 2 C. My initial build attempt was on Mac OS X 10.6, which is a
certified UNIX 03. It didn't. Come to find out that some fellows have
worked out the handful of (relatively simple) patches needed to fix the
#ifdef's for Mac OS X. Seeing as how Axis 2 C purports to be implemented
with portability this wasn't a good start.
I got the sucker built on Mac OS X. After generating the stubs for a
working WSDL (you need to use a Java-based tool to do this), I
discovered real soon that an important struct that is used frequently in
generated stub code (by used I mean often used by value; e.g.
de-referenced pointers) had its full declaration buried in a .c
implementation file for the _library_; not in the corresponding header.
It has been quite a while since I wrote any C prior to this, but I
figured this wasn't quite right. Especially since there was no way the
client code would compile with just the headers for the Axis 2 C
library. So maybe I'm missing something really obvious here, but there's
no denying the fact that in two different ways what should have compiled
out of the box did not. The error was a standard "storage size not
known" kind of thing. It was easy enough to fix (with some refactoring
of the Axis 2 C library, and re-building it), which makes the situation
worse somehow.
I eventually dispensed with Axis 2 C altogether - this experience didn't
make me happy, and a different design decision let me move to
higher-level .NET APIs. NOt to mention, the Axis 2 C API docs sucked, so
I ended up generating some useful ones using Doxygen - another black
mark - *and* the API itself could have been better.
I might note that I ran across one comment by an Axis 2 C developer
where he said that the model to be followed was
"typedef done inside the header and the struct declaration is in
source...in a case you still want to move the struct to the header (it
is not a much recommended approach in c programming) ... [Ed. How-To
description of procedure follows]"
Maybe I missed something in my years away from C, but those
recommendations were new to me.
Case B: I was working with the source code for a Windows printer driver
that I wished to modify. I tried to build it with VC++, several
versions, and just could not easily do it - the code was studded with
UNIX API calls. As soon as I hacked one problem it led to others.
To this day I can't understand why a group of developers - moreover, a
group of developers who were "good" enough to write a working and fairly
sophisticated Windows printer driver - insisted on thoroughly mixing
Windows code with UNIXish code. It's jarring to see the use of UNIX I/O
in the same source along with MS-inspired Hungarian notation and MFC
macros. It's hard to read...plus I hate a lot of those macros.
I eventually only succeeded in building this driver from source by using
a very specific version of the Dev-C++ IDE, namely the one with an exact
version of mingw included. Even a later version of standalone mingw on
the command line, using the *supplied Makefile*, would not build this
driver. It had to be the mingw included with Dev-C++...using that makefile.
Again, maybe it's just me, but this smacks of laziness and user
unfriendliness. I respect the efforts put in by the mingw and cygwin
people, but the point of those is to make it easier to use existing UNIX
stuff on Windows. If you have the opportunity to write a C/C++ Windows
printer driver *from scratch* you write it the Microsoft way, IMHO.
This team did one other thing which I really, really disliked. Their
printer driver - it created image files actually - uses libpng, libjpeg,
libtiff and zlib. Each and every one of these builds OK on Windows,
producing a DLL and LIB along with headers that can be used by other
projects in the usual way...I know, because I've built them on Windows
enough times over the years. What these guys did was pull in all of the
source for these libraries, and bundled them in with their own code. So
the printer driver build was intimately intermingled with compiling and
linking the code for those 4 libraries.
I'm sorry, but that's just not the way it's supposed to work.
In this case too the experience leaves me with the impression that it's
working but substandard C/C++ code. Cutting corners to suit your own
development preferences means you might be cutting corners somewhere else.
AHS