Lint will catch that (almost certainly, but I have not checked), so you could try to make a clean Lint part of your coding standard or checkin requirements.
Funnily enough, I'm currently arguing for exactly that, and citing this very example as a good reason for it.:-)
Bugs are much more likely to be found in an open system such as Linux because of the nature of Open source development - all people using the software can reporting / fixing bugs, not just the limited few inside a company.
The problem is that I disagree with the practical value of this idea.
It's great in theory. Thousands of people all around the world can look over the source code to Linux, and submit their patches and so on. The same goes for any other popular open source project, be it Mozilla, OpenOffice, or whatever.
The problem is that in practice, it doesn't work this way. The vast majority of development work on most big open source projects is actually done by paid professionals, whether they work for Red Hat, or Sun, or IBM, or whoever. You don't really get hundreds of pairs of eyes looking over each line of code that gets submitted. In most cases, even if you have review and super-review on a project, you still may only get a handful of people.
I actually had some personal experiences to help formulate this view. I'm a professional developer, and I use both OO and Moz regularly at home. There were two particular bugs, one in each product, that were really annoying me, nothing spectacular, just little irritations. I decided I'd look around the source to see if I could fix them. I spent most of an afternoon looking around the source code to Moz, and it was still completely incomprehensible to me. It's not that it would be a problem given the time, but as exactly the kind of "opportunistic" helper constantly advocated by the open source world, I just didn't have the time or enthusiasm to invest days in learning my way around. I put up with the bug until the next release instead. And given how much of my spare time I spend keeping sharp and helping out the on-line programming community in other ways, if I gave up, I'd bet that the vast majority of others in my position would too.
The whole "anyone can review and fix it" argument for open source is a great big con, and always has been. It's true in theory, but in practice the barriers to entry are so high that few except for professionals and long-standing volunteers actually do it. Just check the changelogs for your favourite large scale project and see how many different names come up. If the theory is right, there should be hundreds of small contributions by Joe Developers all over the place. Usually, what you actually get is a whole load of things by the same few people.
I would suggest, quite seriously, that procedurally code is often more reviewed in a good commercial outfit with a solid QA set-up than in the open source world. I submit that most of the best open source projects are of the high quality that they are because of the quality of individual developers they attract, in both skill and attitude, and not because of any mass appeal and wide-scale code review.
Sorry, my previous post sounds harsher than intended on re-reading it. My point was that I don't actually buy the mass development argument that open source advocates put forward. Please hop up a level and see my reply to jareth-0205 for more.
Most of the guys I work with can compile their own C++. Then again, they all use VC++ 6 and don't know how scope and for loops are supposed to mix, so no-one else can compile their code. Who would have thought such a simple non-standard behaviour could waste so much time... <sigh>
Better to acknowledge the best-of-breed methodology Microsoft uses to test their OSes, and conclude that while this breed works okay for applications, a world-class operating system needs peer review and distributed open source development to create a quality, secure product.
And that would be Linux, I suppose? Because no bugs ever creep into Linux, and there's never been a security flaw found. Except if you read Bugtraq, of course.
This wasn't even the point of the article -- though it might have been more interesting if it had been -- and yet still someone comes in here and starts making out that Microsoft have bad QA and the open source model is vastly superior. How sad.
Learning a new runtime to learn a new language is not a good tradeoff. With dotNET you learn one runtime, it works for every language.
Or it doesn't work for every language, as the case may be.
The common library will be useful for those who would otherwise have to learn a different GUI or database access or Internet comms library in each language they use. Then again, if you're familiar with GUI programming generally -- event-driven designs, typical WIMP environments, etc. -- then learning a new library doesn't take very long, as they're all much the same anyway. And of course, even then, you probably only learn a small number of such libraries anyway, but you have to keep up to date as they evolve, just as you'll need to with.NET's.
Where.NET, like Java before it, may fall down is the fact that it probably won't be the best UI/DB/comms library for everyone, so the commonality argument is diminished. And of course, there will always be thousands of specialist applications where the.NET library won't offer anything, and in many cases, these will only be developed for the languages of choice in those specialist fields, be they C, LISP, VB, or whatever.
Basically, I think the library commonality argument has some truth in it, but it's vastly overhyped in practice.
If you talk to the Microsoft engineers about dotNET you will find that they consider C++ a legacy language at this point, along with Cobol and Fortran.
Sure, and they'd love to relegate VB6 as well. It's interesting, however, that Microsoft is currently demonstrating more practical support for real (not "Managed") C++ than at any point in its history.
The thing is, if you knock out C++, COBOL, FORTRAN and VB6, you've just ruled out four of the most popular programming languages on the planet, which together with C and Java probably account for, what, 95% of successful projects developed/maintained over the past decade? 98%? 99%? 99.9%?
Compared to these things, C# and VB.NET aren't even a blip in the ocean yet. There is potential in.NET to be sure. We all know there are serious drawbacks to each of those other languages in the wrong context, and we all know better is possible. But the fastest thing to kill.NET will be the attitude that these others are "legacy" languages. "Tried and tested" is the way a smart guy would look at it.
Something else may be better. In fact, it's pretty much a sure thing that sooner or later something else will be better. But if Microsoft's.NET group drop support for the current established big players before they've proven their replacements (and that will take years, if not decades) then they'll reduce their platform to a mere curiosity and not a serious platform for serious developers.
Indirectly, probably your pension firm, your building society, the bank holding your variable interest rate savings account...
Re:C++ will let you do anything!
on
Hijacking .NET
·
· Score: 1
My point was that there's actually no guarantee that v-tables will be used at all. They're an implementation detail, albeit a pretty universal one at present, rather than something required by the definition of C++. The compiler is also allowed to rearrange the members of a class in memory under other circumstances, anyway. For example, it is explicitly allowed to reorder members of a class with access specifiers between them, so just arbitrarily changing a few private keywords to public in a header file is not guaranteed to remove the access protection safely.
Oh, and unfortunately, just having a destructor usually doesn't guarantee the creation of a v-table. That's why there's an explicit rule in the C++ standard that says you have to have a virtual destructor if you want to delete derived objects through a pointer-to-base. Whether destructors should automatically be virtual in a class that has any other virtual methods -- since it makes little sense to have one without the other -- is a subject of debate and an amendment that may go into the next version of the C++ standard.
Of course, all of this is something of a moot point. As I said before, along with many others here, access specifiers in C++ are for the benefit of the programmer, not a security feature. If the programmer attempts to circumvent them by whatever means, it's his problem.
Re:C++ will let you do anything!
on
Hijacking .NET
·
· Score: 1
Of course, this trick doesn't do much good in real classes, since the compiler is free to reorder the class members under several circumstances. There is no guarantee that your malicious class with extra members or changed access specifiers would have the same memory layout as the original for either its data members or its virtual function table (assuming it even has one, though all major implementations use that technique at present).
That doesn't detract from the very valid point that C++ access control is there to help the developer, not to secure code from the end user. It simply demonstrates that the example hacks being thrown around in this thread by people thinking they're clever actually aren't very clever at all.
Memory management and other unnecessary tasks which C++ saddles the developer with do make an impact on either development time, program stability, or both. And that is also true for experienced C++ programmers.
I claim to be an experienced C++ developer. I also claim that if your colleague had bothered to spend just ten minutes learning elementary C++ resource management skills, he would have saved you that half hour, and probably countless other people similar amounts of time over the course of your project.
The problem is that few people bother to make that tiny effort, and then you and I have to clear up the mess a hundred times for every one of them.
...cometh great responsibility. He who cannot handle that power should not take on that responsibility. Thus it always was, and is, and for ever more shall be.
Here endeth today's reading, which was taken from 1 Life, verses 1-3.
Actually, exceptions can impact performance, if you are throwing the exception the majority of the time.
Well, yes, but then they're not really exceptional, are they? Exceptions aren't intended to replace break or if.
The point here is that just having exceptions in the language does not mean all your code runs slower. Contrary to oft-quoted opinion, the zero overhead principle does apply here with modern compilers.
What is the run-time overhead in using templates? At compile time, sure, but at run time there are only benefits.
In theory, that's true at least to a degree, but in practice it tends not to be.
Firstly, you have the bloating issue. On processors which have a relatively small first-level cache (i.e., most of today's major players) having two or three copies of the same algorithm specialised in different ways can be enough to cause cache misses when you're using them in the same area of the code. Having a single algorithm and implicit conversions of the parameters/return value to a common type might not.
Granted you can write your template code as generic wrappers for basic algorithms, but often this is either irrelevant (if you could just let implicit conversions do the job anyway) or awkward (e.g., wrapping a void*-manipulating algorithm in a T*-manipulating template with type parameter T).
Secondly, you have the fact that most library implementations aren't actually very good at providing specialisations where they should. By keeping the algorithm generic, you rely on a generic optimiser rather than the hand-coded, super-efficient assembler that is routine in a typical C library implementation. This one is clearly a quality of implementation issue, but in practice, the bar is pretty low, at least for now.
The use of STL algorithms is usually faster than hand-written loops.
That one's just way off base, I'm afraid. In fact, since most STL implementations are just header files containing templated code because no-one really uses export yet, much of the time the STL algorithms compile down to exactly the same code as an equivalent loop. You sometimes get a modest performance improvement because parameters passed to an STL algorithm are only evaluated once, whereas someone careless who sticks a call to container.length() in his for-loop condition will get it called as a side-effect many times. That's a pretty basic performance issue, though, and something even Joe Average Programmer would knock out if performance was becoming an issue.
But the thing is, web users don't read web sites like books.
Look at the usability research, and a few things are clear. Most web sites are scanned, not read. (The exceptions are things like lengthy articles, but even then, many of these are printed and read from paper anyway.) Hence writing in the same style, and offering the same "mass of text" presentation, as would be appropriate for a book is bad practice for the web.
Most users do not scroll much, if at all. Two of the most used features of the web browsing world are the back button and sites' search facilities, neither of which has a real equivalent in the physical, book-reading world. Books have to have a "one size fits all" approach, while web sites can interact and adapt.
While I take your point about content being dominant, web sites really shouldn't read like books for a whole host of good reasons.
The first mistake, of course, is that people think that (a == b) == a.equals(b) which is, of course, only true if a and b are constant strings or one have invoked intern() on them.
So much for the language that removes all those nasty things that stoopid programmers get wrong. You still have the issue of equality of value vs. equality of identity, you just have nastier syntax for it.
However, both these things are very fundamental Java knowledge and among the first thing you learn when studying Java. It's obvious that you don't start coding serious Java without knowing how try..catch..finally works, and equally obvious that you should the know about the deals with the String class.
Sure. Just as it's obvious that you don't start coding serious C++ without knowing the RAII idiom, you don't start coding serious Perl without understanding the caveats of eq vs. ==, and you don't start coding C without knowing that gets is fundamentally flawed. Except that actually, many people do.
I'm afraid your post actually stands against one of the biggest myths of them all: that Java is much safer than other comparable languages, notably C and C++, because of the limited feature set it provides. The reality is that you can still screw up in Java, and it really isn't much harder than in any other language of a similar level. There are good reasons to use Java for many projects, but immunity from developers who haven't done their homework ain't one of them.
I'm just saying that, over time, you may regret not knowing something well that is, in fact, more efficient and effective for writing compace and fast code.
The problem with this is that it's almost impossible for regular developers to "hand-optimise" their code effectively on any platform today.
Sure, you can write in raw assembler, or you can write in C and be careful of low-level details. But the instruction sets and performance characteristics of modern processors are so counterintuitive at times that usually you're just second-guessing the chip designers, and often you'll be wrong as a result.
There are people who are paid to understand how all the nitty-gritty pipelining, cacheing, and other tricks work in modern processors. They are compiler writers and library implementers. Few other people have the time and resources to invest in acquiring the same level of expertise. Most of us would be better off using a language that is of a generally suitable nature and letting the compiler/interpreter/JIT compiler/optimiser do its thing.
By the way, did you realise that some really quite high level languages now compile down to give more efficient code than C a lot of the time? Why? Because they provide high level features with good underlying implementations that are carefully designed around the target architecture. With a clean programming model, they can often optimise a lot of apparent work away as well. Using a low-level language like C denies the writer of the compiler/optimiser the same degree of assumption, so they can't help you as much as a HLL compiler/optimiser can.
For example, Intel's x86 series chips have REP and CMPSx instructions that seem to be carefully designed to work with strings. Do you know what you see if you look at typical strcmp code in any recent C standard library implementation, though? It looks like a whole mess of random assembler, several lines long, because it's been tuned to the specific target architecture's characteristics. It doesn't look like REP CMPSB.
The whole argument about using low-level languages for efficiency starts to break down around this point. In fact, it's all backwards. The higher the level of language you use, and the cleaner its programming models, the more the compiler/optimiser can help you to get efficient output code. In today's world, you use low-level languages for control and flexibility, but unless you really are an expert on your target architecture, you don't use them for efficiency.
I wonder to what extent this exists in other languages?
The C++ world is full of myths about what does and doesn't enhance performance. Amongst my favourites...
Exceptions cripple performance.
Using virtual member functions cripples performance.
Using templates cripples performance.
In each of these cases, there is some overhead involved if you actually use the language feature, but generally not otherwise with any recent compiler. However, those overheads are usually less than hand-crafting the equivalent functionality (e.g., long jumps, function look-up tables a la C) would incur. Furthermore, if you actually understand the implications of these features, you can keep the overhead way down. The next time I see someone criticise templates for code bloat, and then demonstrate in the next post that they've never come across templated wrappers for generic base classes, I'm going to have to lecture them. }:-)
On the flip side...
Passing by const& always improves performance.
Pointer arithmetic is faster than array indexing.
Making things const helps the optimiser to improve performance.
Most of these get much more credit than they deserve. The first is true often, but not always: it sometimes shafts the optimiser in many compilers. The second is not true with any recent compiler. The third is true sometimes, but not nearly as often as you might expect: optimisers miss many of the apparent (to humans) possibilities anyway, and spot some of the others with or without a const there.
As always, the rule of thumb is to write correct, maintainable code first, and then to use compiler-specific, profiler-induced hackery where (and only where) required. Whether you're writing a database or a graphic engine, this is pretty much always good advice.
But the thing some people don't realise is that the top competitors can also decide to write "industrial-strength" code whenever they want to, with all the meaningful variable names, comments, indenting, reusability, documentation, etc. that you like, and will still beat the pants off of all the regular "real-world" programmers.
That may be true, but I'm not convinced any sort of competition like this proves it. I've met plenty of young, die-hard hackers who could write cute code themselves, but had no teamworking skills whatsoever, including in their coding style. The ability to design and/or implement algorithms that work is not in any way equivalent to the ability to write clean, well-structured, maintainable code. Obviously there's a correlation between the people who have these abilities, but neither implies the other.
They may be young, but they're not inexperienced.
You know, it's funny. When I was a student, I knew everything about coding, too. When I started my first job, I was better than all the other guys there; the older ones got paid way more than me, but wasted loads of time doing pointless things.
I'm reminded of two old aphorisms that are oh-so-true here.
The most important thing you learn as you get older is how much you still have to learn.
Young men believe old men to be fools, but old men know young men to be fools.
For practical programming, when I need an algorithm to solve a problem like these, I go in order of preference: [...] Last resort. Think up clever algorithm.
Sure, but the ability to work out clever algorithms when appropriate is one of the key things that separates a good developer from a code monkey. Is this competition supposed to identify code monkeys or good developers?
But I'd bet the contest winners are pretty smart and I think most of them would make great programmers after a year of work experience.
Yes. I'm not taking anything away from them at all. As the thread title says, I'm just trying to keep the thing in perspective.
I agree that the standard of coding you see in the examples is pretty low by pro standards, and that you'd expect any reasonably experienced pro to come up with better. Then again, as we've all agreed, the nature of this competition does not encourage industrial strength coding. And of course, I don't know about you, but I certainly wrote similar code sometimes when I was a student. The entrants for this sort of competition are young and inexperienced, and you have to look for potential, not results today, if you're going to draw any meaningful conclusions.
What's more concerning, if anything, is that all of the illustrative solutions are basically brute force approaches. If these are the best algorithms available in a sensible timeframe, perhaps the problems set weren't such a good choice. If there are significantly better algorithms available and the coders weren't finding them, maybe either the time constraints were too restrictive or maybe even the top guys in a competition like this are still quite a way behind the "serious coder" standard (professional or otherwise).
Funnily enough, I'm currently arguing for exactly that, and citing this very example as a good reason for it. :-)
The problem is that I disagree with the practical value of this idea.
It's great in theory. Thousands of people all around the world can look over the source code to Linux, and submit their patches and so on. The same goes for any other popular open source project, be it Mozilla, OpenOffice, or whatever.
The problem is that in practice, it doesn't work this way. The vast majority of development work on most big open source projects is actually done by paid professionals, whether they work for Red Hat, or Sun, or IBM, or whoever. You don't really get hundreds of pairs of eyes looking over each line of code that gets submitted. In most cases, even if you have review and super-review on a project, you still may only get a handful of people.
I actually had some personal experiences to help formulate this view. I'm a professional developer, and I use both OO and Moz regularly at home. There were two particular bugs, one in each product, that were really annoying me, nothing spectacular, just little irritations. I decided I'd look around the source to see if I could fix them. I spent most of an afternoon looking around the source code to Moz, and it was still completely incomprehensible to me. It's not that it would be a problem given the time, but as exactly the kind of "opportunistic" helper constantly advocated by the open source world, I just didn't have the time or enthusiasm to invest days in learning my way around. I put up with the bug until the next release instead. And given how much of my spare time I spend keeping sharp and helping out the on-line programming community in other ways, if I gave up, I'd bet that the vast majority of others in my position would too.
The whole "anyone can review and fix it" argument for open source is a great big con, and always has been. It's true in theory, but in practice the barriers to entry are so high that few except for professionals and long-standing volunteers actually do it. Just check the changelogs for your favourite large scale project and see how many different names come up. If the theory is right, there should be hundreds of small contributions by Joe Developers all over the place. Usually, what you actually get is a whole load of things by the same few people.
I would suggest, quite seriously, that procedurally code is often more reviewed in a good commercial outfit with a solid QA set-up than in the open source world. I submit that most of the best open source projects are of the high quality that they are because of the quality of individual developers they attract, in both skill and attitude, and not because of any mass appeal and wide-scale code review.
Sorry, my previous post sounds harsher than intended on re-reading it. My point was that I don't actually buy the mass development argument that open source advocates put forward. Please hop up a level and see my reply to jareth-0205 for more.
Most of the guys I work with can compile their own C++. Then again, they all use VC++ 6 and don't know how scope and for loops are supposed to mix, so no-one else can compile their code. Who would have thought such a simple non-standard behaviour could waste so much time... <sigh>
And that would be Linux, I suppose? Because no bugs ever creep into Linux, and there's never been a security flaw found. Except if you read Bugtraq, of course.
This wasn't even the point of the article -- though it might have been more interesting if it had been -- and yet still someone comes in here and starts making out that Microsoft have bad QA and the open source model is vastly superior. How sad.
Yep; compiled Perl already approximates the readability of the original pretty well anyway. :-p
Or it doesn't work for every language, as the case may be.
The common library will be useful for those who would otherwise have to learn a different GUI or database access or Internet comms library in each language they use. Then again, if you're familiar with GUI programming generally -- event-driven designs, typical WIMP environments, etc. -- then learning a new library doesn't take very long, as they're all much the same anyway. And of course, even then, you probably only learn a small number of such libraries anyway, but you have to keep up to date as they evolve, just as you'll need to with .NET's.
Where .NET, like Java before it, may fall down is the fact that it probably won't be the best UI/DB/comms library for everyone, so the commonality argument is diminished. And of course, there will always be thousands of specialist applications where the .NET library won't offer anything, and in many cases, these will only be developed for the languages of choice in those specialist fields, be they C, LISP, VB, or whatever.
Basically, I think the library commonality argument has some truth in it, but it's vastly overhyped in practice.
Sure, and they'd love to relegate VB6 as well. It's interesting, however, that Microsoft is currently demonstrating more practical support for real (not "Managed") C++ than at any point in its history.
The thing is, if you knock out C++, COBOL, FORTRAN and VB6, you've just ruled out four of the most popular programming languages on the planet, which together with C and Java probably account for, what, 95% of successful projects developed/maintained over the past decade? 98%? 99%? 99.9%?
Compared to these things, C# and VB.NET aren't even a blip in the ocean yet. There is potential in .NET to be sure. We all know there are serious drawbacks to each of those other languages in the wrong context, and we all know better is possible. But the fastest thing to kill .NET will be the attitude that these others are "legacy" languages. "Tried and tested" is the way a smart guy would look at it.
Something else may be better. In fact, it's pretty much a sure thing that sooner or later something else will be better. But if Microsoft's .NET group drop support for the current established big players before they've proven their replacements (and that will take years, if not decades) then they'll reduce their platform to a mere curiosity and not a serious platform for serious developers.
Indirectly, probably your pension firm, your building society, the bank holding your variable interest rate savings account...
My point was that there's actually no guarantee that v-tables will be used at all. They're an implementation detail, albeit a pretty universal one at present, rather than something required by the definition of C++. The compiler is also allowed to rearrange the members of a class in memory under other circumstances, anyway. For example, it is explicitly allowed to reorder members of a class with access specifiers between them, so just arbitrarily changing a few private keywords to public in a header file is not guaranteed to remove the access protection safely.
Oh, and unfortunately, just having a destructor usually doesn't guarantee the creation of a v-table. That's why there's an explicit rule in the C++ standard that says you have to have a virtual destructor if you want to delete derived objects through a pointer-to-base. Whether destructors should automatically be virtual in a class that has any other virtual methods -- since it makes little sense to have one without the other -- is a subject of debate and an amendment that may go into the next version of the C++ standard.
Of course, all of this is something of a moot point. As I said before, along with many others here, access specifiers in C++ are for the benefit of the programmer, not a security feature. If the programmer attempts to circumvent them by whatever means, it's his problem.
Of course, this trick doesn't do much good in real classes, since the compiler is free to reorder the class members under several circumstances. There is no guarantee that your malicious class with extra members or changed access specifiers would have the same memory layout as the original for either its data members or its virtual function table (assuming it even has one, though all major implementations use that technique at present).
That doesn't detract from the very valid point that C++ access control is there to help the developer, not to secure code from the end user. It simply demonstrates that the example hacks being thrown around in this thread by people thinking they're clever actually aren't very clever at all.
I claim to be an experienced C++ developer. I also claim that if your colleague had bothered to spend just ten minutes learning elementary C++ resource management skills, he would have saved you that half hour, and probably countless other people similar amounts of time over the course of your project.
The problem is that few people bother to make that tiny effort, and then you and I have to clear up the mess a hundred times for every one of them.
...cometh great responsibility. He who cannot handle that power should not take on that responsibility. Thus it always was, and is, and for ever more shall be.
Here endeth today's reading, which was taken from 1 Life, verses 1-3.
Well, yes, but then they're not really exceptional, are they? Exceptions aren't intended to replace break or if.
The point here is that just having exceptions in the language does not mean all your code runs slower. Contrary to oft-quoted opinion, the zero overhead principle does apply here with modern compilers.
In theory, that's true at least to a degree, but in practice it tends not to be.
Firstly, you have the bloating issue. On processors which have a relatively small first-level cache (i.e., most of today's major players) having two or three copies of the same algorithm specialised in different ways can be enough to cause cache misses when you're using them in the same area of the code. Having a single algorithm and implicit conversions of the parameters/return value to a common type might not.
Granted you can write your template code as generic wrappers for basic algorithms, but often this is either irrelevant (if you could just let implicit conversions do the job anyway) or awkward (e.g., wrapping a void*-manipulating algorithm in a T*-manipulating template with type parameter T).
Secondly, you have the fact that most library implementations aren't actually very good at providing specialisations where they should. By keeping the algorithm generic, you rely on a generic optimiser rather than the hand-coded, super-efficient assembler that is routine in a typical C library implementation. This one is clearly a quality of implementation issue, but in practice, the bar is pretty low, at least for now.
That one's just way off base, I'm afraid. In fact, since most STL implementations are just header files containing templated code because no-one really uses export yet, much of the time the STL algorithms compile down to exactly the same code as an equivalent loop. You sometimes get a modest performance improvement because parameters passed to an STL algorithm are only evaluated once, whereas someone careless who sticks a call to container.length() in his for-loop condition will get it called as a side-effect many times. That's a pretty basic performance issue, though, and something even Joe Average Programmer would knock out if performance was becoming an issue.
But the thing is, web users don't read web sites like books.
Look at the usability research, and a few things are clear. Most web sites are scanned, not read. (The exceptions are things like lengthy articles, but even then, many of these are printed and read from paper anyway.) Hence writing in the same style, and offering the same "mass of text" presentation, as would be appropriate for a book is bad practice for the web.
Most users do not scroll much, if at all. Two of the most used features of the web browsing world are the back button and sites' search facilities, neither of which has a real equivalent in the physical, book-reading world. Books have to have a "one size fits all" approach, while web sites can interact and adapt.
While I take your point about content being dominant, web sites really shouldn't read like books for a whole host of good reasons.
So much for the language that removes all those nasty things that stoopid programmers get wrong. You still have the issue of equality of value vs. equality of identity, you just have nastier syntax for it.
Sure. Just as it's obvious that you don't start coding serious C++ without knowing the RAII idiom, you don't start coding serious Perl without understanding the caveats of eq vs. ==, and you don't start coding C without knowing that gets is fundamentally flawed. Except that actually, many people do.
I'm afraid your post actually stands against one of the biggest myths of them all: that Java is much safer than other comparable languages, notably C and C++, because of the limited feature set it provides. The reality is that you can still screw up in Java, and it really isn't much harder than in any other language of a similar level. There are good reasons to use Java for many projects, but immunity from developers who haven't done their homework ain't one of them.
Would it be silly to point out, that given the "zero overhead" principle of C++, those two statements are contradictory?
The problem with this is that it's almost impossible for regular developers to "hand-optimise" their code effectively on any platform today.
Sure, you can write in raw assembler, or you can write in C and be careful of low-level details. But the instruction sets and performance characteristics of modern processors are so counterintuitive at times that usually you're just second-guessing the chip designers, and often you'll be wrong as a result.
There are people who are paid to understand how all the nitty-gritty pipelining, cacheing, and other tricks work in modern processors. They are compiler writers and library implementers. Few other people have the time and resources to invest in acquiring the same level of expertise. Most of us would be better off using a language that is of a generally suitable nature and letting the compiler/interpreter/JIT compiler/optimiser do its thing.
By the way, did you realise that some really quite high level languages now compile down to give more efficient code than C a lot of the time? Why? Because they provide high level features with good underlying implementations that are carefully designed around the target architecture. With a clean programming model, they can often optimise a lot of apparent work away as well. Using a low-level language like C denies the writer of the compiler/optimiser the same degree of assumption, so they can't help you as much as a HLL compiler/optimiser can.
For example, Intel's x86 series chips have REP and CMPSx instructions that seem to be carefully designed to work with strings. Do you know what you see if you look at typical strcmp code in any recent C standard library implementation, though? It looks like a whole mess of random assembler, several lines long, because it's been tuned to the specific target architecture's characteristics. It doesn't look like REP CMPSB.
The whole argument about using low-level languages for efficiency starts to break down around this point. In fact, it's all backwards. The higher the level of language you use, and the cleaner its programming models, the more the compiler/optimiser can help you to get efficient output code. In today's world, you use low-level languages for control and flexibility, but unless you really are an expert on your target architecture, you don't use them for efficiency.
The C++ world is full of myths about what does and doesn't enhance performance. Amongst my favourites...
In each of these cases, there is some overhead involved if you actually use the language feature, but generally not otherwise with any recent compiler. However, those overheads are usually less than hand-crafting the equivalent functionality (e.g., long jumps, function look-up tables a la C) would incur. Furthermore, if you actually understand the implications of these features, you can keep the overhead way down. The next time I see someone criticise templates for code bloat, and then demonstrate in the next post that they've never come across templated wrappers for generic base classes, I'm going to have to lecture them. }:-)
On the flip side...
Most of these get much more credit than they deserve. The first is true often, but not always: it sometimes shafts the optimiser in many compilers. The second is not true with any recent compiler. The third is true sometimes, but not nearly as often as you might expect: optimisers miss many of the apparent (to humans) possibilities anyway, and spot some of the others with or without a const there.
As always, the rule of thumb is to write correct, maintainable code first, and then to use compiler-specific, profiler-induced hackery where (and only where) required. Whether you're writing a database or a graphic engine, this is pretty much always good advice.
That may be true, but I'm not convinced any sort of competition like this proves it. I've met plenty of young, die-hard hackers who could write cute code themselves, but had no teamworking skills whatsoever, including in their coding style. The ability to design and/or implement algorithms that work is not in any way equivalent to the ability to write clean, well-structured, maintainable code. Obviously there's a correlation between the people who have these abilities, but neither implies the other.
You know, it's funny. When I was a student, I knew everything about coding, too. When I started my first job, I was better than all the other guys there; the older ones got paid way more than me, but wasted loads of time doing pointless things.
I'm reminded of two old aphorisms that are oh-so-true here.
Sure, but the ability to work out clever algorithms when appropriate is one of the key things that separates a good developer from a code monkey. Is this competition supposed to identify code monkeys or good developers?
Yes. I'm not taking anything away from them at all. As the thread title says, I'm just trying to keep the thing in perspective.
Sorry, I stand corrected. That's what I get for posting after a 30s scan of the example solutions while at work. :o)
The first two solutions are both pretty much brute force, though.
OK, reading in detail the problems aren't the same after all.
I agree that the standard of coding you see in the examples is pretty low by pro standards, and that you'd expect any reasonably experienced pro to come up with better. Then again, as we've all agreed, the nature of this competition does not encourage industrial strength coding. And of course, I don't know about you, but I certainly wrote similar code sometimes when I was a student. The entrants for this sort of competition are young and inexperienced, and you have to look for potential, not results today, if you're going to draw any meaningful conclusions.
What's more concerning, if anything, is that all of the illustrative solutions are basically brute force approaches. If these are the best algorithms available in a sensible timeframe, perhaps the problems set weren't such a good choice. If there are significantly better algorithms available and the coders weren't finding them, maybe either the time constraints were too restrictive or maybe even the top guys in a competition like this are still quite a way behind the "serious coder" standard (professional or otherwise).