Err, I pointed out that Assembler is not a good choice. As for maintainability, C++ often loses out to C because of inheritance. I find that I often have to dig through layers of it to find the method that I'm looking for, having first ascertained which class to start from (which of course depends on the type of the pointer used to call the method).
As for writing my own I/O library, if I'm forced to use C++, then I usually fallback on C stdio as there is inevitably a call to synchronise the two in the code already. Then all I need to do is reimplement realloc using a templated function, and I'm cooking with gas. It woul still be better if the C++ library was an improvement over the C one, rather than being incomplete, incompatible and a pain in the arse to use.
When you need high performance, C++ is better choice than any other language.
Bullshit, C is. Assembler (just for the pedants) is too labour intensive and platform specific to be a good choice. With C++, lots of the features that on the face of them seem to be improvements over C, are in fact far less performant than C. Consider the "one size fits all" and implicit copying of the STL, or the brainfuck that is the iostream library once you actually want to format something.
It's not that simple anymore.. but anyway, I've always hated having to create a fake class just to be able to have a main in Java.
Well, having to create a "fake" class for your main() method is hardly a complaint - nothing "fake" about the class, and it enables you to knock up a quick test harness or to have multiple entry points to a system. It's definitely better than having to use the preprocessor to hide multiple main functions in a bunch of C++ classes. As for the simplicity of Java, the underlying bytecode format has hardly changed since 1.1, even with the addition of generics. The language itself has also been remarkably stable between versions, and the API in the accompanying class library has mostly become simpler (see the Collections classes for instance) although it has grown exponentially as more classes have been added.
> where the inevitable trade offs left C++ inadequate in every paradigm
Err. No. Sorry. No, There, you have your unsubstantiated opinion, I have mine
My opinion yes, but substantiated by my experience and that of others I have worked with and respect. an opinion that is also shared by the authors of a number of articles, books and studies that show programmer efficiency is higher when working with Java rather than C++. This efficiency is partly down to the complexity of C++ - it is undeniably harder to master - but the comparative benefit of mastering that complexity is debatable. A consensus is even forming that Java has had its day, and that things like Ruby may be more programmer efficient (see "Beyond Java" by Bruce Tate for instance).
Had C++ been standardised in 89, perhaps it would have been an elegant language without some of extra complexity that was documented in each edition of Stroustrup's book. As for reading the standard, no thanks. The fact that I cannot think of a good C++ book ("C++ Primer" is just as terrible as "The C++ Programming Language" for example) just reinforces the fact that C++ is complex, and doesn't make me anymore inclined to resort to the standard as a reference.
Your swipes at the Sun compiler miss my point - GCC is a poorer compiler for my target platform anyway - I was simply highlighting the implementation dependent gotchas that STL introduced. I don't want to need to know the most optimal way of using a each STL, I'd rather have a language and accompanying library that are simple enough that they offer abstractions I can use efficiently without the implementation specific knowledge.
Finally, as for the Perl code, it's not my ideal way forward. More of a damning indictment of C++ that it's easier for many of my colleagues to develop parallel tools in Perl, a langauge not known for encouraging the writing of maintainable code.
To paraphrase something I read a while ago, there's an elegant language fighting to find its way out of the elephantine bulk of C++, and it's Java.
PostgreSQL lacks many of the advanced features of those products [Oracle, DB/2], and is not as fast either.
True, but if you lack a quality DBA and the hardware necessary to get the maximum performance from Oracle or DB/2, then PostgreSQL is a fine alternative. Oracle in particular needs a lot of care and attention to keep it performing at its best, and if you've forked out for the licenses you probably want to get them most from it. It's in situations where the budget or other resources rule out the big commercial DB's that PostgreSQL really shines. It has excellent documentation (which I find much more readable and complete than MySQL's, especially when it comes to tuning options) and is not very complex to administer. In fact, unless there is a compelling reason to go with another DB, then PostgreSQL is always my first choice.
Java for example is simple, because there are only vert few implementations in existance
The reason Java is simple is that it didn't try to be a multi-paradigm language, where the inevitable trade offs left C++ inadequate in every paradigm. Java was also well described in a decent specification rather than being standardised too late in the day as happened with C++. There also exists a canonical Java test suite, whereas the C++ standard is littered with opportunities for implementation specific functionality, especially in the STL.
Also the STL is not that complex as you think and it really is efficient, if used correctly.
I can write efficient code for Sun's implementation of the STL that will generate multiple calls to the copy constructor in GNU STL when adding an object to a container. Neither STL version violates semantics as described in Stoustrup's book, it's just one of a vast number of implementation specific features that are allowed in an STL implementation.
There is no all-purpose language that is ALWAYS simple, efficient and elegant.
No, but I struggle to think of a single instance where I have encountered C++ code that proved to be simpler, more maintainable or more efficient than the equivalent written in C, Perl or Java. Of the three large C++ based projects that I have become involved with, two were scrapped and replaced with a mix of C and Java. The third is still proving to be a hindrance to those trying to maintain and extend it, so much so that a parallel system is evolving, largely written in Perl.
Re:it's a rather straightforward observation
on
Tim Bray Says RELAX
·
· Score: 1
XML was intended to be easy to PARSE, not easy to read.
Correct, XML is slightly easier to parse because of explicit end tags but most people disabled short tag support and enforced end tags in SGML anyway (in the syntax declaration and DTD respectively). However, saying that XML is not as easy to read as SGML is stretching things a bit - I find them to have the same legibility, although when using namespaces in XML I find they tend to result in long tag names that obscure things a bit. The things that appeared to be novel or improvements in XML were the discarding of the antiquated syntax declaration (a hangover from early GML days) and the concept of "well formed XML" without explicitly requiring a DTD.
Was that at some hotel in Swindon, UK? If so then I was there as well, if not then it must have been very shortly after the announcement, as XML (along with XSL) dominated the meeting. When XSL was described by a heavily bearded academic guy, several of the audience members became apoplectic. Apparently they thought DSSSL was a better alternative, something that amused me as all the DSSL tools I was aware of were either incomplete or as fiddly as fuck to work with.
C++ defines container classes which cannot overflow. Try using them next time you write some C++ code.
No, the STL defines container classes, and they suck just as badly as the C++ language itself. Performance goes out he window unless you spend inordinate amounts of time ensuring that all the classes you put into the containers are setup to avoid multiple copying. This is a major pain in the arse, as different implementations of the STL have different semantics, and "accepted best practice" is to not to hold a copy rather than a reference to an object in a container. As someone else points out above, STL has encouraged generic programming, which is a major brainfuck which I've only seen used by l33t programmers who shouldn't be allowed near a compiler in the first place. The general attitude I see amongst self-acknowledged C++ programmers is "fuck design, screw maintainabilty, where can I slip some more operator overloading and inheritance into this crock of shit".
Quite honestly, I wish Stroustrup had never been allowed the opportunity to inflict C++ on the programming world. C is concise, and despite it's flaws (which are mostly design trade offs) can be used with good practices to produce maintainable and scalable code. C++ on the other hand adds nothing more to C than complexity, throwing away the possible benefits of OO. In fact, until I was exposed to Java I couldn't see any benefit to OO programming thanks to the way it has been implemented in C++.
A doctor at the last hospital I was in seem to disagree with you. The guy in the next bed had accidentally touched an exposed high power cable, which resulted in burning away the tips of his fingers and severe burns elsewhere. On the card describing his condition, the doctor had clearly written "electrocution".
Just google "linus" and "solaris" and see how dismissive he is of it, calling it "a joke", just like he's been dismissive of the BSDs.
Which probably explains why it's taken Linux so long to start resembling the Solaris kernel in terms of architecture. Linux was a poor second to the BSD's in the early to mid 1990's because it was largely written by hobbyists who didn't have the resources or knowledge that had been fed into Unix over 20 odd years. Until 2.6, Linux was a poor second to Solaris because of Linus's unwillingness to listen to people who had looked beyond the confines of the Linux kernel. People who had looked at the design of Solaris were forever making comments to the effect that Solaris had done x and acheived y, while Linus was floundering about looking for answers to things like sophisticated SMP support, threading and a decent scheduler. The Solaris kernel is still way more sophisticated than Linux, it's just the userland that needs an overhaul - and no, that doesn't mean importing gobs of poorly or inaccurately documented GNU tools...
Your stretching it a bit by belittling Apple. They and NeXT did the impossible - they made Unix really, really usable. I speak as someone who bought a Mac intending to stick NetBSD or Yellow Dog Linux on it, only to end up sticking to OS X because I find it so easy to live with.
I guess this is another thing to add to the MySQL gotchas page. Of course, in a decent database engine, like PostgreSQL, if you alter a column data type then the indexes are updated to reflect this.
Err, no one of the founders threw a hissy fit because he'd fucked up the administrative side of the NetBSD Foundation. An ill informed "debate" on Slashdot followed. NetBSD is still going strong, often providing new features like SMP support that then filter into the other BSDs (OpenBSD in the case of SMP). Recently, a new Bluetooth stack was integrated into the main codebase and dozens of new drivers - some ported from the other BSDs, others written specifically for NetBSD. NetBSD is also the first choice of BSDs for running Xen, and has also been used to set an Internet2 Land Speed Record (improving on the previous Linux entry by 50%, despite running on a considerably slower machine).
You've pretty much described my opinion on the matter. However, there's an ongoing battle between the project manager, who wants shot of him, and human resources who are on the other side of the country and don't give a shit about discipline in our office. In the meantime I've suggested locking down his computer with Fedora or CentOS and a BIOS password.
If you like source based packaging systems, then NetBSD is a better choice than Gentoo. I have the misfortune to work with someone who insists on using Gentoo on his work machine. He's a lazy sod, but even if he wasn't he would still be unable to do much work because usually his machine is either grinding through another rebuild or awaiting a reinstall because a half-baked update has rendered it unbootable. If you want binary packages, the quarterly releases of pkgsrc are excellent - and far more reliable than Debian in my experience (for instance, GCJ has been dumping core for at least a week on the Debian box here at work - I'm about to see if this mornings update cures it).
As someone else pointed out, the command line tools are the usual way to configure a BSD system. It should be emphasised though, that compared to Linux the tools are far more consistent and better documented. This is true of all the BSD's but especially OpenBSD. Compare this with Linux where the tools are from disparate sources, and the man pages are often omitted or incomplete. Yeah, there might be an out of date HOWTO on the web that can help, but that's not much use when your trying to get a machine online in the first place. The consistency of the BSD's is a consequence of developing a complete operating system, not stitching together the entire system from a mass of poorly integrated sources.
Finally, having all the architectures built out of the same tree means far less breakage than with Linux. I've run Linux on PA-RISC and Sparc machines in the past, and it's frustrating when the vanilla kernel can only be trusted to work out of the box on x86. If you're trying to track the latest development you end up having to marshal patches from various sources in the hope of keeping things going - with NetBSD it's just a CVS update from one repository.
Nope, the string format field width should be at least one byte less than the array to allow for a null. See the description of the 's' format in the scanf(3) manpage.
I seem to recall having to reboot into some sort of virtual machine to run Windows under OS/2. However with OpenBSD Linux emulation, I can run a Linux executable as though it was a native one. The difference is that they they run on a more secure operating system and (at least with FreeBSD and NetBSD Linux emulation) they sometimes run faster. Now that the Sun JDK is running native on FreeBSD and NetBSD, the last reason I have for running Linux binaries on a BSD is gone - however emulation keeps the door open for others who want to run some binary only Linux app on BSD.
Apple haven't pulled support for writing Cocoa apps in Java with 10.4, however they do discourage it. If you work through the tutorial with XCode 2.4 on Tiger, it still works.
Quite an old book, but it is great for learning how to identify dubiously structured code and then improve it.
Advanced C++ Programming Styles and Idioms J. Coplien
Again, quite an old book, but it covers "programming in the large" rather than than the nuts and bolts that many books describe.
Design Patterns G. Booch, et al
I was initially underwhelmed by this book, partly because the hype surrounding it was so great, and because I had already been using a number of the patterns without knowing it thanks to Java. However, the really useful patterns are nicely presented.
Apart from books, I learned a lot from picking over things like Glib, the utility library that underpins GTK+. The code is of a very high quality and includes a number of interesting ideas.
As well as programming languages themselves, it's worthwhile looking at things like unit testing and design aids such as UML. The Java web development gurus have focused a lot of peoples attention on the benefits of truly modular code, dependency injection, testing and so forth. This largely stems from the pain of early Java web development and a general dissatisfaction with EJB. I certainly feel I'm a much better C and C++ programmer as a result of doing a lot of Java work in recent years.
Err, I pointed out that Assembler is not a good choice. As for maintainability, C++ often loses out to C because of inheritance. I find that I often have to dig through layers of it to find the method that I'm looking for, having first ascertained which class to start from (which of course depends on the type of the pointer used to call the method).
As for writing my own I/O library, if I'm forced to use C++, then I usually fallback on C stdio as there is inevitably a call to synchronise the two in the code already. Then all I need to do is reimplement realloc using a templated function, and I'm cooking with gas. It woul still be better if the C++ library was an improvement over the C one, rather than being incomplete, incompatible and a pain in the arse to use.
When you need high performance, C++ is better choice than any other language.
Bullshit, C is. Assembler (just for the pedants) is too labour intensive and platform specific to be a good choice. With C++, lots of the features that on the face of them seem to be improvements over C, are in fact far less performant than C. Consider the "one size fits all" and implicit copying of the STL, or the brainfuck that is the iostream library once you actually want to format something.
It's not that simple anymore.. but anyway, I've always hated having to create a fake class just to be able to have a main in Java.
Well, having to create a "fake" class for your main() method is hardly a complaint - nothing "fake" about the class, and it enables you to knock up a quick test harness or to have multiple entry points to a system. It's definitely better than having to use the preprocessor to hide multiple main functions in a bunch of C++ classes. As for the simplicity of Java, the underlying bytecode format has hardly changed since 1.1, even with the addition of generics. The language itself has also been remarkably stable between versions, and the API in the accompanying class library has mostly become simpler (see the Collections classes for instance) although it has grown exponentially as more classes have been added.
> where the inevitable trade offs left C++ inadequate in every paradigm
Err. No. Sorry. No, There, you have your unsubstantiated opinion, I have mine
My opinion yes, but substantiated by my experience and that of others I have worked with and respect. an opinion that is also shared by the authors of a number of articles, books and studies that show programmer efficiency is higher when working with Java rather than C++. This efficiency is partly down to the complexity of C++ - it is undeniably harder to master - but the comparative benefit of mastering that complexity is debatable. A consensus is even forming that Java has had its day, and that things like Ruby may be more programmer efficient (see "Beyond Java" by Bruce Tate for instance).
Had C++ been standardised in 89, perhaps it would have been an elegant language without some of extra complexity that was documented in each edition of Stroustrup's book. As for reading the standard, no thanks. The fact that I cannot think of a good C++ book ("C++ Primer" is just as terrible as "The C++ Programming Language" for example) just reinforces the fact that C++ is complex, and doesn't make me anymore inclined to resort to the standard as a reference.
Your swipes at the Sun compiler miss my point - GCC is a poorer compiler for my target platform anyway - I was simply highlighting the implementation dependent gotchas that STL introduced. I don't want to need to know the most optimal way of using a each STL, I'd rather have a language and accompanying library that are simple enough that they offer abstractions I can use efficiently without the implementation specific knowledge.
Finally, as for the Perl code, it's not my ideal way forward. More of a damning indictment of C++ that it's easier for many of my colleagues to develop parallel tools in Perl, a langauge not known for encouraging the writing of maintainable code.
To paraphrase something I read a while ago, there's an elegant language fighting to find its way out of the elephantine bulk of C++, and it's Java.
PostgreSQL lacks many of the advanced features of those products [Oracle, DB/2], and is not as fast either.
True, but if you lack a quality DBA and the hardware necessary to get the maximum performance from Oracle or DB/2, then PostgreSQL is a fine alternative. Oracle in particular needs a lot of care and attention to keep it performing at its best, and if you've forked out for the licenses you probably want to get them most from it. It's in situations where the budget or other resources rule out the big commercial DB's that PostgreSQL really shines. It has excellent documentation (which I find much more readable and complete than MySQL's, especially when it comes to tuning options) and is not very complex to administer. In fact, unless there is a compelling reason to go with another DB, then PostgreSQL is always my first choice.
Java for example is simple, because there are only vert few implementations in existance
The reason Java is simple is that it didn't try to be a multi-paradigm language, where the inevitable trade offs left C++ inadequate in every paradigm. Java was also well described in a decent specification rather than being standardised too late in the day as happened with C++. There also exists a canonical Java test suite, whereas the C++ standard is littered with opportunities for implementation specific functionality, especially in the STL.
Also the STL is not that complex as you think and it really is efficient, if used correctly.
I can write efficient code for Sun's implementation of the STL that will generate multiple calls to the copy constructor in GNU STL when adding an object to a container. Neither STL version violates semantics as described in Stoustrup's book, it's just one of a vast number of implementation specific features that are allowed in an STL implementation.
There is no all-purpose language that is ALWAYS simple, efficient and elegant.
No, but I struggle to think of a single instance where I have encountered C++ code that proved to be simpler, more maintainable or more efficient than the equivalent written in C, Perl or Java. Of the three large C++ based projects that I have become involved with, two were scrapped and replaced with a mix of C and Java. The third is still proving to be a hindrance to those trying to maintain and extend it, so much so that a parallel system is evolving, largely written in Perl.
XML was intended to be easy to PARSE, not easy to read.
Correct, XML is slightly easier to parse because of explicit end tags but most people disabled short tag support and enforced end tags in SGML anyway (in the syntax declaration and DTD respectively). However, saying that XML is not as easy to read as SGML is stretching things a bit - I find them to have the same legibility, although when using namespaces in XML I find they tend to result in long tag names that obscure things a bit. The things that appeared to be novel or improvements in XML were the discarding of the antiquated syntax declaration (a hangover from early GML days) and the concept of "well formed XML" without explicitly requiring a DTD.
I was at SGML '96 where XML was first announced
Was that at some hotel in Swindon, UK? If so then I was there as well, if not then it must have been very shortly after the announcement, as XML (along with XSL) dominated the meeting. When XSL was described by a heavily bearded academic guy, several of the audience members became apoplectic. Apparently they thought DSSSL was a better alternative, something that amused me as all the DSSL tools I was aware of were either incomplete or as fiddly as fuck to work with.
C++ defines container classes which cannot overflow. Try using them next time you write some C++ code.
No, the STL defines container classes, and they suck just as badly as the C++ language itself. Performance goes out he window unless you spend inordinate amounts of time ensuring that all the classes you put into the containers are setup to avoid multiple copying. This is a major pain in the arse, as different implementations of the STL have different semantics, and "accepted best practice" is to not to hold a copy rather than a reference to an object in a container. As someone else points out above, STL has encouraged generic programming, which is a major brainfuck which I've only seen used by l33t programmers who shouldn't be allowed near a compiler in the first place. The general attitude I see amongst self-acknowledged C++ programmers is "fuck design, screw maintainabilty, where can I slip some more operator overloading and inheritance into this crock of shit".
Quite honestly, I wish Stroustrup had never been allowed the opportunity to inflict C++ on the programming world. C is concise, and despite it's flaws (which are mostly design trade offs) can be used with good practices to produce maintainable and scalable code. C++ on the other hand adds nothing more to C than complexity, throwing away the possible benefits of OO. In fact, until I was exposed to Java I couldn't see any benefit to OO programming thanks to the way it has been implemented in C++.
... that Slashdot editors can't spell
Non-fatal shocking is not electrocution.
A doctor at the last hospital I was in seem to disagree with you. The guy in the next bed had accidentally touched an exposed high power cable, which resulted in burning away the tips of his fingers and severe burns elsewhere. On the card describing his condition, the doctor had clearly written "electrocution".
No, but there's a strong connection between onanism and the study of Computer Science.
What about the other 23%?
Just google "linus" and "solaris" and see how dismissive he is of it, calling it "a joke", just like he's been dismissive of the BSDs.
Which probably explains why it's taken Linux so long to start resembling the Solaris kernel in terms of architecture. Linux was a poor second to the BSD's in the early to mid 1990's because it was largely written by hobbyists who didn't have the resources or knowledge that had been fed into Unix over 20 odd years. Until 2.6, Linux was a poor second to Solaris because of Linus's unwillingness to listen to people who had looked beyond the confines of the Linux kernel. People who had looked at the design of Solaris were forever making comments to the effect that Solaris had done x and acheived y, while Linus was floundering about looking for answers to things like sophisticated SMP support, threading and a decent scheduler. The Solaris kernel is still way more sophisticated than Linux, it's just the userland that needs an overhaul - and no, that doesn't mean importing gobs of poorly or inaccurately documented GNU tools ...
Your stretching it a bit by belittling Apple. They and NeXT did the impossible - they made Unix really, really usable. I speak as someone who bought a Mac intending to stick NetBSD or Yellow Dog Linux on it, only to end up sticking to OS X because I find it so easy to live with.
I guess this is another thing to add to the MySQL gotchas page. Of course, in a decent database engine, like PostgreSQL, if you alter a column data type then the indexes are updated to reflect this.
As an added bonus, this could all be funded by selling the extracted salt to crisp companies.
Err, no one of the founders threw a hissy fit because he'd fucked up the administrative side of the NetBSD Foundation. An ill informed "debate" on Slashdot followed. NetBSD is still going strong, often providing new features like SMP support that then filter into the other BSDs (OpenBSD in the case of SMP). Recently, a new Bluetooth stack was integrated into the main codebase and dozens of new drivers - some ported from the other BSDs, others written specifically for NetBSD. NetBSD is also the first choice of BSDs for running Xen, and has also been used to set an Internet2 Land Speed Record (improving on the previous Linux entry by 50%, despite running on a considerably slower machine).
You've pretty much described my opinion on the matter. However, there's an ongoing battle between the project manager, who wants shot of him, and human resources who are on the other side of the country and don't give a shit about discipline in our office. In the meantime I've suggested locking down his computer with Fedora or CentOS and a BIOS password.
I've found doing anything in *BSD is more painful than it should be.
I'm struggling to think of an example. For instance, installing init scripts for third party software is far more painful on Linux:
cp foo.sh /etc/init.d/ /etc/init.d/foo.sh /etc/rcS.d/K69foo /etc/init.d/foo.sh /etc/rc0.d/K69foo /etc/init.d/foo.sh /etc/rc1.d/K69foo /etc/init.d/foo.sh /etc/rc2.d/K69foo /etc/init.d/foo.sh /etc/rc3.d/S69foo
/etc/init.d/foo.sh start
ln
ln
ln
ln
ln
Unless your Linux distribution supports one of the other half-baked init schemes of course.
Meanwhile, on NetBSD it's:
cp foo.sh /etc/rc/ /etc/rc.conf (add the line foo=YES)
/etc/rc/foo start
vi
Basically, anything administrative I can think of is more tedious or complex on Linux than on NetBSD.
If you like source based packaging systems, then NetBSD is a better choice than Gentoo. I have the misfortune to work with someone who insists on using Gentoo on his work machine. He's a lazy sod, but even if he wasn't he would still be unable to do much work because usually his machine is either grinding through another rebuild or awaiting a reinstall because a half-baked update has rendered it unbootable. If you want binary packages, the quarterly releases of pkgsrc are excellent - and far more reliable than Debian in my experience (for instance, GCJ has been dumping core for at least a week on the Debian box here at work - I'm about to see if this mornings update cures it).
As someone else pointed out, the command line tools are the usual way to configure a BSD system. It should be emphasised though, that compared to Linux the tools are far more consistent and better documented. This is true of all the BSD's but especially OpenBSD. Compare this with Linux where the tools are from disparate sources, and the man pages are often omitted or incomplete. Yeah, there might be an out of date HOWTO on the web that can help, but that's not much use when your trying to get a machine online in the first place. The consistency of the BSD's is a consequence of developing a complete operating system, not stitching together the entire system from a mass of poorly integrated sources.
Finally, having all the architectures built out of the same tree means far less breakage than with Linux. I've run Linux on PA-RISC and Sparc machines in the past, and it's frustrating when the vanilla kernel can only be trusted to work out of the box on x86. If you're trying to track the latest development you end up having to marshal patches from various sources in the hope of keeping things going - with NetBSD it's just a CVS update from one repository.
Nope, the string format field width should be at least one byte less than the array to allow for a null. See the description of the 's' format in the scanf(3) manpage.
Or even:
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
// do stuff ...
for (String s = in.readLine(); s != null; s = in.readLine()) {
}
Just like OS/2 could run Windows executables.
I seem to recall having to reboot into some sort of virtual machine to run Windows under OS/2. However with OpenBSD Linux emulation, I can run a Linux executable as though it was a native one. The difference is that they they run on a more secure operating system and (at least with FreeBSD and NetBSD Linux emulation) they sometimes run faster. Now that the Sun JDK is running native on FreeBSD and NetBSD, the last reason I have for running Linux binaries on a BSD is gone - however emulation keeps the door open for others who want to run some binary only Linux app on BSD.
Apple haven't pulled support for writing Cocoa apps in Java with 10.4, however they do discourage it. If you work through the tutorial with XCode 2.4 on Tiger, it still works.
C++ Programming Style by T. Cargill
Quite an old book, but it is great for learning how to identify dubiously structured code and then improve it.
Advanced C++ Programming Styles and Idioms J. Coplien
Again, quite an old book, but it covers "programming in the large" rather than than the nuts and bolts that many books describe.
Design Patterns G. Booch, et al
I was initially underwhelmed by this book, partly because the hype surrounding it was so great, and because I had already been using a number of the patterns without knowing it thanks to Java. However, the really useful patterns are nicely presented.
Apart from books, I learned a lot from picking over things like Glib, the utility library that underpins GTK+. The code is of a very high quality and includes a number of interesting ideas.
As well as programming languages themselves, it's worthwhile looking at things like unit testing and design aids such as UML. The Java web development gurus have focused a lot of peoples attention on the benefits of truly modular code, dependency injection, testing and so forth. This largely stems from the pain of early Java web development and a general dissatisfaction with EJB. I certainly feel I'm a much better C and C++ programmer as a result of doing a lot of Java work in recent years.