Programming Mistakes To Avoid
snydeq writes "InfoWorld's Peter Wayner outlines some of the most common programming mistakes and how to avoid them. 'Certain programming practices send the majority of developers reaching for their hair upon opening a file that has been exhibiting too much "character." Spend some time in a bar near any tech company, and you'll hear the howls: Why did the programmer use that antiquated structure? Where was the mechanism for defending against attacks from the Web? Wasn't any thought given to what a noob would do with the program?' Wayner writes. From playing it fast and loose, to delegating too much to frameworks, to relying too heavily on magic boxes, to overdetermining the user experience — each programming pitfall is accompanied by its opposing pair, lending further proof that 'programming may in fact be transforming into an art, one that requires a skilled hand and a creative mind to achieve a happy medium between problematic extremes.'"
What common mistakes do you frequently have to deal with?
And now for the printable version with all the tips on one page:
http://infoworld.com/print/145292
Y
What common mistakes do you frequently have to deal with?
- Software only tested by programmer.
- Manual only written by programmer.
- Support can't do a day without programmer.
A good programmer should know when to delegate. Or their boss should. Depends on office culture perhaps.
Hivemind harvest in progress..
...just try to avoid errors and you should be set.
Until you spend enough time with it, to learn why the original programmer did as he did.
As I see it, most projects start out with a good structure and the best of intentions, and then comes deadlines and the developer having to juggle several projects at once, and then a shortcut is taken here, then there. And suddenly you end up with a non-documented project where the only person that knows how it works is the original developer.
There will however always be BAD code by bad programmers. I've taken over Java progress where everything was OOP'ed into hell (as in a bazillion classes more than was needed for the application) and PHP projects which should be OOP'ed but consisted of about 500 files that included each other in a huge confusing net.
I've also had to take over projects where the original developer was using new technology because he thought it would be fun (at the expense of the customer). Having a huge website in PHP/MySQL and then having crucial parts of it in Ruby/PostreSQL is just a maintenance nightmare.
My <1000 UID is with a hot chick
Equating web programming with all programming.
Learing how to do it in the first place.
Programming mistake No. 1: Playing it fast and loose
Failing to shore up the basics is the easiest way to undercut your code. Often this means overlooking how arbitrary user behavior will affect your program. Will the input of a zero find its way into a division operation? Will submitted text be the right length? Have date formats been vetted? Is the username verified against the database? Mistakes in the smallest places cause software to fail.
Fair enough. So debug while you code. Seems like good advice.
Programming mistake No. 2: Overcommitting to details
On the flip side, overly buttoned-up software can slow to a crawl. Checking a few null pointers may not make much difference, but some software is written to be like an obsessive-compulsive who must check that the doors are locked again and again so that sleep never comes.
Doesn't mistake number 2 contradict number 1? Or am I missing something? I guess he's saying debug while you code, but not too much. After reading the rest I see that that was his algorithm for writing the whole article. Rule 1: do x; Rule 2: But not too much! I didn't really find the article all that useful.
All programming should be assembly language programming anyway and a lot of his rules don't seem to apply to assembly language programming. Remember rules aren't necessary when you are a programming god who only codes directly in machine opcodes. Even assemblers are for weenies. Man up and become one with the machine!
Quite an experience to live in fear, isn't it? That's what it is to be a slave.
The most common programming mistake to avoid: Reading badly written articles about "what programming mistakes to avoid".
Doesn't mistake number 2 contradict number 1? Or am I missing something?
Yup. FTA:
Below you will find the most common programming pitfalls, each of which is accompanied by its opposing pair, lending further proof that programming may in fact be transforming into an art -- ...
Hivemind harvest in progress..
I very rarely see programming mistakes. There seems to be 2 kinds of programmers.
- Those who care about what they do and try hard.
- Those who don't care about what they do and don't try hard
The later write terrible code, but it is just because they are either lazy or aren't suited to the profession and can't get enthused. Very rarely do you see someone who cares about there work make a big mistake (and if so they are probably just starting out).
Programming mistake #0: Believing that your computer degree (Computer Engineering or Computer Science alike) automatically puts your code in a high level of quality.
Not to bring any academia vs industry argument, but many students miss the idea of a Computer degree with programming courses in it: The degree intentionally doesn't go to details because it needs to give you a background into a broader set of subjects. Industry needs one to be very attentive to details in that one thing he's doing at the moment.
The only common mistake I see is not firing the programmer who makes any of those "common" mistakes. There is absolutely no reason for any of this shit to be "common" unless "programmers" who make them are uneducated dumbasses who should never be allowed anywhere near software development.
Now, please, give me the list of "common mistakes" made by surgeons and aircraft engineers, and compare them with this list of amateurish crap.
Contrary to the popular belief, there indeed is no God.
Unless you're coding in machine opcodes like a previous poster suggested, you're already losing some optimization potential by relying on the compiler/interpreter to do it for you. Even in C you're relying heavily on machine generated code. So why is garbage collection so bad?
It seems to me like the structured programming debate all over again.
Dilbert RSS feed
Pointer typedefs were a bad idea in the 1980s. They're just terrible today. One pet peeve of mine is this:
typedef struct _FOO { int Blah; } FOO, *PFOO;
void
SomeFunction(const PFOO);
That const doesn't do what you think it does. There was never a good reason to use pointer typedefs. There is certainly no good reason to do so today. Just say no. If your coding convention disagrees, damn the coding convention.
He gives one example of an attempt to avoid null pointer errors in Java next:
public String getFirstName(Person person) {
return person?.getName()?.getGivenName();
}
But is it a good idea to use null to mean "no value specified"? What would be better, and what are the tradeoffs? Storing 0 or ""? Storing a special (constant/static) instance object nullValue?
I'm not a lawyer, but I play one on the Internet. Blog
So why is garbage collection so bad?
'cause it tends to flush predictability right down the toilet. When is the garbage collector going to swing around to do its thing? Are you *sure* it's going to be when it has enough time to do so? Or is it going to pick exactly the wrong moment? Am I going to run out of memory at an awkward time triggering a collection of thousands of objects I haven't used in ages?
Yes, all of these have perfectly valid workarounds.
However, then you are right back to knowing exactly what your compiler and environment are going to do, and sometimes even holding its hand. Manually triggering a collection isn't all that different from handling memory management yourself.
The Right Tool for the Right Job sometimes is low level. And by the way, many great programmers know quite well what the compiler will do with particular important bits of code, and if they do not, will invoke the compiler to generate assembly or intermediate-language code to be sure. Yes, in garbage-collected languages too, I've used ILDASM quite a bit to know what C#/.NET was doing, exactly.
1) VB
2) Perl
3) Silver bullets
3) Writing your own "framework".
4) Using somebody else's "framework".
No folly is more costly than the folly of intolerant idealism. - Winston Churchill
Is it indecent of me to reminisce on the days of olde when such a topic would simply turn into a lengthy discussion mocking BASIC programmers?
Violence is the last refuge of the incompetent. Polar Scope Align for iOS
#1 - If you are a programmer, BE A PROGRAMMER and manage the pointers and memory allocations yourself. Garbage collection is for little boys. Men deal with it on their own with techniques that work and are efficient.
So mega-strongly disagree dude. Not saying you shouldn't do heavy lifting when necessary -- just that you should only do it when necessary. Don't re-invent the wheel every time. Frameworks exist that do work for you for a reason. Chose your frameworks well, understand them in depth, and you can do good things. If you "start from the first principles" every time, you end up with a humongous fucking surface of new code -- which is bound to have a nasty bug or three. It comes down to choosing the best tools for the job.
#2 - Initialize all variables to known values. int i; doesn't cut it. int i=0; does.
True dat. Lots security pitfalls here too -- not just garden variety bugs.
#3 - Use descriptive variable names
So true. Corollary to that: because a variable name is descriptive, don't make wanton assumptions about it.
#4 - you shouldn't be allowed to program anything new until you've been a maintenance programmer for a few years and seen the crap code that others puke into the world. Your crap code stinks too, BTW.
I'd modify this to say "always, always, always have a peer-review process". Junior devs are prevented from checking in crap because it gets caught by senior devs. The junior devs also learn quality habits from reviewing senior devs' code. Multiple reviewers is always a good thing. Review your design among the entire team before anyone writes a single line of code. Remember to keep security in mind when reviewing code. Use static analyzers when you're done with the "human" aspect of the review. Apply every imaginable quality bar to your code, and only check it in once it has passed scrutiny.
I'm supposed to program mistakes to avoid what?
I've not worked as a programmer for, hmm, maybe 15 years and all of this was known way back even before I "retired" from that line of work. Perhaps all these levels of abstraction upon abstraction make things harder to understand. Back in my days these "pitfalls" were obvious because we all (well, not all, but a lot) knew ASM and actually even used it regularly (even inline, *shudder*).
Someone above mentioned pointer typedefs and gave the example of typedef struct { int Blah; } FOO, *PFOO; (yes I left off the bit before the the opening brace deliberately.) and then suggesting that people don't know that void SomeFunction (const PFOO) {} doesn't behave as expected. Now this could, I suppose, be seen as a failure of the language. But, shit, any idiot who understands the underlying logic can see why that causes problems. Which goes back to my point of maybe all these modern levels of abstraction and getting away from the machine are, in some ways, detrimental.
Now, get off my lawn. Umm, except I don't have a lawn because I sprayed the growth inducing hormone RoundUp all over it, but that is beside the point. I think.
Always think of your code as some sort of API if you care about clean, maintainable code. This is a good talk about API and code design: http://www.youtube.com/watch?v=aAb7hSCtvGw/ from Josh Bloch. It's entertaining too.
On second thought, let's not go to Camelot. It is a silly place.
All true. My personal favorites are larger, long running projects where all of the above is true and all kinds of undocumented business logic is embedded in the code making a rewrite unfeasable and you have to decide which part of the code is outright sloppy or bad, which parts are feasable and which parts aren't actually being used anymore. Top that off with the original developers being unavailable (either dead or fleeing) and you'd be painting a pretty accurate run-of-the-mill software enviroment.
---
"The chances of a demonic possession spreading are remote -- relax."
I often deliberately choose a string manipulation that involves strcpy() and even strcat(), just to make a point that those are perfectly valid and useful functions, despite some morons writing insecure code with them.
The only really unsafe function is gets().
Contrary to the popular belief, there indeed is no God.
I did went throught the list in TFA and while their "programming mistakes" list is sound, it's all over the place and often doesn't dig down to why should you do or not a certain thing.
So I decided to put down a list of, low level principles and concerns to consider when doing software. Given my own level of experience and the fact that I'm getting tired of maintining code by people who have never managed to cross the threshold from junior/medior software designer to senior designer, that is the target audience.
So here goes:
- When designing/coding software, assume that sooner or later it's going to be called-by/changed/extended by a junior developer. They cannot be relied on to recognize design structures or practices and will do things like passing bad parameters in, or incorrectly use it (for example, misusing a singleton). My solution to this is defensive design/coding: check for nulls at library entry points and fail-fast (avoid "junk-in junk-out" scenarios - those just make for data corruption and hard to track bugs), make sure things like singleton classes cannot be instanciated normaly, avoid obscure constructs that must be used in a "right way" (i.e. functions that should be called in a certain order) and overall try and make your design so that the natural way of using it is also the correct way.
- When designing software, before employing a certain construct (for example a design pattern) ask yourself "What do I want to achieve with it?". Complex software structures are used instead of simple (and easier to understand) ones because they achieve certain objectives which outweight the increase in complexity - don't use it because it's fancy/fashionable/elegant/everybody-does-it: those are not proper reasons. The cost to maintain, support and extend code grows with code size and complexity and using fancy structures just because is a way to dig a deep hole for your colleagues and your future self. Consider that it's allways cheaper to "add it later if and when we need it" than "maintain code that is twice the size for 6 months". For example, what is achieved by defining an interface for which now (and in the foreseeable future) only one implementation exists?
- Design and code your software so that Responsabilities and Domain-knowledge are contained together in their own modules/classes. Avoid leakage of concerns (i.e. "we do it this way here because we know that the code we call in another module works in such and such way"). This makes it easier to find ALL the code responsible for doing a certain kind of thing and avoids the dreaded "I changed it in one place but forgot to change it in another place" problem. For example, don't mix your database access code (that knows all about SQL and tables and such) with your web-page generation code (which is experting in user interaction via HTML) since they are independent domains (you can have one without the other).
Being still employed by the company when the project goes overtime and over budget.
Experienced programmers should've found another employer at a higher salary before their incompetence is discovered....
Donte Alistair Anderson Roberts - hi son!
Karma: Chameleon
There will however always be BAD code by bad programmers. I've taken over Java progress where everything was OOP'ed into hell (as in a bazillion classes more than was needed for the application) and PHP projects which should be OOP'ed but consisted of about 500 files that included each other in a huge confusing net.
I see this one as a lack-of-experience problem. People have good intentions and want to build scalable, extensible, maintainable code. This is good. Unfortunately however, they're wrong. The apps they're building are small irregardless of the amount of thought they put into them, and they won't have to scale and extend the way they think they might - you don't need interfaces and impls and arbitrary inheritance for everything when the webapp is 4 screens of Spring WebFlow! Sure, if you're building something that warrants it, this is the way to go, but most of aren't building apps that big or flexible. It seems to take time to learn this, and to know when to apply the patterns and when to just build it.
As a smarter man than I once said, Make things as simple as possible, but no simpler. If you do that, your code will work, it'll be understandable by the next guy, and you'll have a fighting chance of meeting your deadlines.
Forget thrust, drag, lift and weight. Airplanes fly because of money.
public String getFirstName(Person person) {
return person?.getName()?.getGivenName();
}
WTF?
'The tyrant will always find pretext for his tyranny.' - Aesop's Fables
Half of these are design mistakes
did you forget to take your meds?
I often deliberately choose a string manipulation that involves strcpy() and even strcat(), just to make a point that those are perfectly valid and useful functions, despite some morons writing insecure code with them.
The only really unsafe function is gets().
That's just stubbornness for it's own sake. These are violently unsafe functions. People do manage to make asses of themselves even with so-called 'safe' string APIs, but there's no good reason to not use them. Strcpy() or strcat() have pitfalls that are really esoteric, and if you keep using them you'll eventually make a mistake and end up with some absolute motherfucker of a bug with security ramifications you wouldn't even have imagined.
Just add more code! That always makes it better. Closely followed by "It's unreliable/broken" "We've got to rewrite that old xxxx in m$'s new blah-ty-blah framework!".
-- Programming with boost is like building a house with lego. It's a cool but I wouldn't want to live in it
My two most common mistakes:
Crumb's Corollary: Never bring a knife to a bun fight.
Allowing too many options / features in the design. The classic example being unable to decide whether feature A or B is best, and ducking the issue by including them both
Assuming 5 working-days of effort can be achieved in a working week. Conveniently forgetting about all the office overheads such as "progress" meetings, timesheet administration, interrupted work, all the other concurrent projects. Even the most efficient, single-threaded operation needs half a working-day per week just for the trivia.
Following on from that, conveniently forgetting about annual leave commitments, national holidays and the possibility of sickness. If 5 working-days per week is impractical, 12 working-months in a year is downright negligent.
The tacit assumption that testing will inevitably be followed by reelase - rather than bug-fixing.
Holding the end-date constant while delaying the start, or presuming that all delays in the specification, design, approval stages can somehow be reclaimed during coding (how: by thining faster?)
politicians are like babies' nappies: they should both be changed regularly and for the same reasons
The biggest programming mistakes I've had the displeasure of making, or discovering in others code, almost always centre around one of these two problems:
1. The code is over-engineered
2. The code was abstracted before there was even a need for the abstraction.
I remember when I was less experienced, how thrilled I'd be over code that was clever, solved many problems aside from the one I was trying to solve, and had some clear reusability built in. What a work of art, I thought.... until I eventually realised that much of the extra code I had written didn't get used, the abstracted code was never reused - or even if it was, I couldn't predict how it would be reused and the abstraction was clumsy at best, useless at worst.
It's sad when this happens - good intentions, but the end result is a lot of waste. I'm embarrassed to look over my earlier code which is like this.. I like to think I do it less now, but the temptation is always there... I'm going to need to do this later anyway... I can just abstract this bit here and reuse it some day in the future...
My advice now... Don't do it! Just wait until the reuse case comes along, or the new feature request comes along, and *then* do it. You'll know so much more about the problem domain then, or you might avoid days (weeks!) of wasted effort.
If you are a programmer, BE A PROGRAMMER and manage the pointers and memory allocations yourself
I look at the problem like this;
I've solved a fair number of sudoku puzzles in my time. You build a mental set of rules and patterns you look for, and you repeatedly apply them to the remaining squares. On a really hard puzzle you'll often reach a point where you get stuck. You keep scanning for patterns in the remaining numbers but you just can't see the one clue that causes the rest of the solution to fall out.
But a computer program? Once you tell it how to find something, it never forgets to apply a rule. You may think you can keep following a small set of simple rules while building a complex software solution. But chances are pretty good that you'll miss something. If you can hand a task like memory management to a software solution, there's a good chance it will do a better job at tracking memory than you will.
09F91102 no, 455FE104 nope, F190A1E8 uh-uh, 7A5F8A09 that's not it, C87294CE no. Ah! 452F6E403CDF10714E41DFAA257D313F.
>> 'programming may in fact be transforming into an art, one that requires a skilled hand and a creative mind to achieve a happy medium between problematic extremes.'"
Its not transforming into it, it's always been an art. And that has got nothing to do with whether its web programming or not.
The reason that this is even news to some people is that most managers fight hard to bury that fact, because the vast majority of them are one-trick ponies that incorrectly think that everything can and should be reduced into a plannable production line process, and that we developers are all simply non-creative, cheap and freely interchangeable commodity called a 'coder'.
Admitting programming is an art makes management have to admit that:
1) Not all programmers are the same therefore we have value, so need to be paid appropriately.
2) Its not a predictable process so you can't micro-manage us.
These are violently unsafe functions.
If those are unsafe, then dereferencing a pointer or using an array is unsafe, too -- and that means, a programmer is unable to write safe code no matter what.
People do manage to make asses of themselves even with so-called 'safe' string APIs, but there's no good reason to not use them.
What?
The only kind of "safe" strings handling that I am aware of, is operations on strings that are combined with allocation (in object-oriented or almost-object-oriented way). Their purpose is to simplify common operations, any "safety" is at best a side effect that shouldn't matter if programmer is not a moron in the first place.
Strcpy()
strcpy()
Case-sensitive names should be written as they are defined, no matter where they are in a sentence.
or strcat() have pitfalls that are really esoteric, and if you keep using them you'll eventually make a mistake and end up with some absolute motherfucker of a bug with security ramifications you wouldn't even have imagined.
I repeat -- if you can mess up strcpy(), you can mess up anything, and should not be allowed to write any code to begin with. It does not matter how many opportunities you are given to jump in front of a bus or a train -- what is important is that you should not do it.
Contrary to the popular belief, there indeed is no God.
I hate it when some enterprising test engineer decides to add a constant value in place of the instrument reading to force a pass.
Then when you 'fix' this, the shit hits the fan cause you're the one who has 'broke it'. (Not that the DUT's are faulty)
Especially love it when it's on a testset for a train's break force tests...
Comment removed based on user account deletion
I was recently working on a horribly written .Net app that created and de-referenced tons of objects in its main loop. The net result was memory usage going from 200MB one second to 500MB another second. Based on how quickly over all system memory was cleared up, the .Net GC must kick in right away. I'm not talking about objects lingering around for minutes or even tens of seconds, I'm talking about just a few seconds.
If you're going to gripe about using a language that uses a GC, then it's perfectly valid to gripe about ANY abstraction you use between you and the computer to program. Like any tool, it can be incorrectly used.
Never code anything important between 1PM and 3PM (or whatever is your most sleepy time of the day based on your circadian rhythm).
sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
(How about a Java application where a block of simple, everyday fixed classes were written in Groovy? See; nothing changes. New toys used to make the same old mistakes.)
From scarped cliff or quarried stone she cries "A thousand types are gone, I care for nothing, no not one."
This one bugs the hell out of me:
:= assignments, but instead to a SELECT DECODE FROM dual.
In PL/SQL, when people for some bizarre reason avoid using IF/THEN/ELSE and normal
Why?! Dear Lord why?
It's harder to read. It's slower. It's against normal practises. It's an utterly unecessary use of SELECT.
So why do they do it? And why do they insist - when I point out their stupidity - that it's "just developer preference" and "there's no performance hit"?
HELP ME!
Don't get me started on preventing programming mistakes. If I'd address the most common programming mistakes that I've ran into in the wild and write an article about each of those mistakes at a time, I would end up with a whole book on the matter and would probably call it "Growing Better Software".
I find the given top 12 list of mistakes a bit weak- I'd be able to avoid all of these and yet write horrible code. My personal recommendation for a top 12 of programming mistakes to avoid would be:
1. Failing to check function parameters before using them: null pointers, limits, lengths, etc. This will make your program unstable and/or unpredictable.
2. Spending too little time thinking about and designing the data structure of the application. This will make you get stuck when maintaining/extending your application.
3. Following every market hype - When the marketing bubble bursts, you'll have to start over again.
4. Designing user interfaces without actually involving users - You'll be surprised how easy it is to confuse users.
5. Infinitely deeply nested if/else statements - This will make code absolutely unreadable.
6. No documentation whatsoever - Who's going to maintain your code after you change jobs?
7. Ignoring existing, universally accepted standards - so you'll cause interoperability issues or be doomed to either reinvent the wheel.
8. Hard-coded values/magic numbers - as a result, any change must be made in code rather than allowing power users to configure their own system.
9. Littering code with global variables - this implies statefulness of code, making it pretty near impossible to predict how a function will behave next time it is called.
10. Being unaware of the "Big O" order of your algorithms, causing code to be unnecessarily inefficient.
11. Strong platform dependency: This can shorten the lifetime of your application to whenever the next platform upgrade takes place, or keep you stuck at the current version of the current platform forever.
12. Thinking you can figure out everything by yourself - In learning by doing, experience can only follow from making mistakes. By getting yourself a mentor or an education, you can actually learn from the mistakes that thousands have made before you.
13. Stopping at 12.
Visit http://ringbreak.dnd.utwente.nl/~mrjb/growingbettersoftware to download your free copy of the book
"Now, please, give me the list of "common mistakes" made by surgeons and aircraft engineers, and compare them with this list of amateurish crap." - by Alex Belits (437) * on Tuesday December 07, @05:57AM (#34471506) Homepage
Back in 1996-1997, I had a programming contract with a MAJOR "eisenhower military industrial complex" company (who shall remain nameless).
Each day during work, I had to go report to a major in the military who was my supervisor right after lunch at noon or thereabouts, to go over code I was writing for them.
In doing so to get to his office, I would have to pass through an aircraft hanger (underground no less & connected to a major airforce base in the south eastern US) where they were making both troop transports, bombers, and jet-fighters, etc..
At the far end of the hanger was a sign that read this:
"DO YOUR BEST WORK, BECAUSE OUR YOUNG MEN & WOMEN'S LIVES RIDE ON IT"
That got to me, as I had a family member currently in the service.
So, one day, I happened to be walking through it with the major at my side who was my supervisor.
First pass through, He noticed that I looked at that sign then... and I did so, again, on the way back when he & I passed back through it to get back to his offices from where I was working.
He, upon noticing I kept staring in the direction of that sign each time we went thru said hanger, asked:
"What do you keep looking at over there in that direction?"
I replied "That sign. I have a younger brother in the armed forces (who is now currently a major himself no less a decade later now) and that sign 'gets to me'"
To which he replied "Ok, 'off the record'?"
I said "Sure, ok..."
To which he stated "Kid, I don't want to 'burst your bubble' but that sign? Is bullshit!"
To which I said "What do you mean?"
To which he finally stated "The reason WHY we have this contract is, we are the 'lowest bidder' & those planes?? They are built like shit!"
To which I asked "Why do you say that?"
He closed it with "Ok - each arch in the airframe is SUPPOSED to have 10 rivets - we only put in 7 - just to save money & make contract budget + to profit!" (or something FAR less than what it was supposed to be by the intended design, etc.)
(This made me also realize that big business does this for profit, and hell with peoples' lives... even those of those who defend us).
Sure, the planes were going to get "torn up" & shot at anyhow, but to make them shabbier than intended, violating the engineering team's init. designs, doesn't help with them being able to TAKE such abuse either... FAR from it, imo @ least!
How would you all like to know this & see it happen, and know that YOUR brother OR sister in the military was riding on aircraft that were built far less structurally sound than they should have been according to their intended design... especially when said planes would be getting into fights in the air?
APK
P.S.=> That's my story in regards to "mistakes" (intentional ones in the NAME OF PROFIT, hell with lives) being made in warfare aircraft of all kinds being made. I hope I didn't offend anyone with it, but there it is! Enjoy... apk
Programming without carefully selecting the solution. I maintain a small measurement control system and before even making the smallest extension i will read and think about the different possibilities in question before typing the first line of code. Then i will try to isolate the new code so that a possibly wrong decision at that stage can be cured quickly.
So lets condense it to: Think hard and try to make the right decision and still assume it will be wrong.
A special corollary of this is to give a malus to all solutions which needlessly bind you a specific implementation.
try maintaining code written by an architect
currently i have a couple of bugs to fix on a system which, functionality wise isnt all that incredibly exciting, however the system was written entirely in a one man sprint by a design-happy architect. The end result is so complex it took him over four hours to explain just the easy half of the project..
People, what a bunch of bastards
Ignoring team dynamics
If you get a software lead that is a primadonna, thinking he knows absolutely everything without listening to anyone including the project lead, customers or his own developers (I've been there), the project is doomed to fail. Doesn't matter what it is, when the team works poorly, the output is crap.
My advice to everyone is if you have a team member that is more of an obstacle than an asset, and everything turns into an argument, then get rid of him as fast as you can.
Tesla was a genius. Edison however was a overrated hack who liked to torture puppies.
There will however always be BAD code by bad programmers. I've taken over Java progress where everything was OOP'ed into hell (as in a bazillion classes more than was needed for the application) and PHP projects which should be OOP'ed but consisted of about 500 files that included each other in a huge confusing net.
Taking over projects fitting those descriptions is never a good idea. They are nothing but pain, it's impossible to resolve the problems with the app and the code unless you opt for a complete rewrite. If, however, you go that route the remaining developers will be pissed off because they wrote the crappy code and you are basically saying that their ugly baby is ... well ... UGLY! What's worse, you are saying it out loud for everybody including the PHBs to hear. Eventually you end up being frustrated, your PHB either caves in to complaints about you and puts you in your place or you get laid off. Unless, of course, you anticipate this and quit before he gets the chance. There is no substitute for writing code properly and designing and planning your application properly no matter how insignificant the application seems to be because you will never know which piece of shit app will take off and scale into something much, much bigger. Myself, I learned this from a friendly lecture I was given by my boss after I handed in my first project on my very first job. He made me rewrite the thing entirely claiming it was better that I learned the value of things like database abstraction and MVC separation right away. He was right.
Only to idiots, are orders laws.
-- Henning von Tresckow
YES !! It was originally that way. An ART form. Managers FINALLY figured out how to cram programming into a 'form' (cookie cutter), and used all the early idiotic "Design Methods" to corral programmers & designers into lower paying, easily replaceable "jobs". The "systems programmers" at CNA (early 1980s) would wear flannel shirts while everyone else got sent home if not wearing a suit. That kind of power could not go unpunished. (I.E.: we helped in our own demise.)
Or when BAD programmers, think they are good, and label other programmers as BAD. Which one are you?
Politics is the art of looking for trouble, finding it everywhere, diagnosing it incorrectly and applying the wrong fix.
Number one: ignoring users.
In my dream world, every programmer would be required to spend one day a week working on the help desk, just to get a chance to see what is important to the actual people who use the software.
http://www.geoffreylandis.com
are very important. I work in the embedded field, and it can be quite a pain in the ass to throughly test something without having a set of unit tests. It helps to have a mindset of encapsulating modules or groups of work, and abstract out the platform (at build time) if possible. Then have a set of unit tests that exercise the code that can run on your desktop machine. Doing this lends well to code responsible for doing calculations, that is often bug ridden if not unit tested.
#2 - Initialize all variables to known values. int i; doesn't cut it. int i=0; does.
True dat. Lots security pitfalls here too -- not just garden variety bugs.
Just wanted to point out that this doesn't apply in all languages. When dealing with languages where int i; does initialize to a known value, it's unnecessary (though not wrong) to do int i=0;. For example, most languages that aren't C or C++. If you're coding in Java, you know that if you do int i; it will be initialized to 0 for you.
Where you want to advise someone in one direction,
but then on the very next line you warn them not to go too far?
It makes the entire message a little watered down. They're all good points, in various scenarios, but the lesson I learned out of that was to do something in between both of the extremes... which is what I'm doing now. Huh, and here I just thought I was lazy.
I certainly have sympathy for you; I've taken over many code bases which were maintenance nightmares.
But I have to take exception (no pun intended) with your above statement. What you took over was not OOP in any way.
OO is not "do all the same crap but do it using copious amounts of inheritance."
I've seen people do what you describe---using an insane mount of classes---and it's abominable, but please don't pin that on OO. The whole point of OO is to minimize the need for looking through code, by making each class simple and opaque with a well-defined contract, so it can be treated like a black box as much as possible.
Most people who venture into OO just do all sharing of data and/or functionality via inheritance. I blame most CS curricula for this, as CS has taught for many decades that languages are all the same and just impose a few different syntax rules on what should be the same logic. Thus, most CS students see inheritance just another syntactic tool, and they are eager to make excessive use of it so they can feel like they're doing things the "Java way" (or .Net way, etc.).
And to try to be a little on topic: the article is quite correct that Java's new question-mark gimmick (the implicit null check) is one of the worst things to happen to software reliability in the last ten years.
The Internet is full. Go away.
#2 - Initialize all variables to known values. int i; doesn't cut it. int i=0; does.
True dat. Lots security pitfalls here too -- not just garden variety bugs.
This is a pet peeve of mine. It's very bad advice to throw in meaningless initializations. If a variable has no meaningful value, you want tools like valgrind to be able to recognize this and catch code that tries to use this value. If you set it to 0, but then don't mean that variable to be read without being set to something else first, you've done yourself a disservice.
I told the boss "I don't write perfect code, and that's why we have testers." That day I was fired. A week later the test lead was laid off.
6 months later the company lost the contract and the manager was laid off...
Best Slashdot Co
I could write articles like this in my sleep. It is vague and schizophrenic. Don't use frameworks that take care of common functionality, but don't reinvent the wheel. Ok? Use syntax that doesn't exist yet. Even better! Now write code that is long enough to get the job done, but not too long. Why didn't I think about that?! Waste of time
#1 - If you are a programmer, BE A PROGRAMMER and manage the pointers and memory allocations yourself.
And output formatting. printf is for wussies. Also, networking; if you can't whip up your own application-tailored TCP stack, then you should go back to playing with VB. And GUI toolkits? TOOLKITS?!? What are you doing, building a footstool? Hell, no! Manly programmers don't use toolkits, they use the library of macros they built while apprenticing to Knuth.
You're completely right. All this mamby-pamby resource management crap is for Kindergartners and Excel users. Real Programmers flip bits with soldering irons, and we like it this way.
Dewey, what part of this looks like authorities should be involved?
There is one mistake made by experienced (C++) programmers that really bugs me: fear of decisions. Every time this programmer needs to design something, he tries really hard to not place any constraints on the design until it becomes absolutely impossible to create an implementation without doing so. He separates interface from implementation. Then he separates the implementation from the real implementation by some indirect pattern like pimpl. (Heaven forbid that the API user would ever have to recompile!) He places no constraints on parameter values and spends months ensuring that the code handles each one, somehow, even for parameter values that clearly indicate that the caller royally screwed up. He makes all code reusable, even if nobody will ever do so. He writes all his code in templates, just in case the API user might want to write his own string class. He invents his own scripting language (with freeform syntax and comments and God knows what other features) and writes configuration files in it, just so the user could configure every possible variable in the program and to do it in the most ingenuous and convoluted manner.
To top it off, he then takes all of the above and puts it in a library. Never mind that he has never tried to use it with anything but the one little app he is currently writing. Never mind that the library is so bloated that linking to it would triple the memory footprint of OpenOffice. Never mind that nobody in the right mind would even consider using it. But it's OPEN SOURCE, man, so it must be GOOD!
My first job I came across /*Why did I do this?*/ above two pages (when printed out) of uncommented code. Code that started with
if(pow(2,(typeof(int)somenumber){while(something){for{...two pages of stuff}}}
He was, it turned out, checking to see if bits in an int (a 16 bit int) were set in order to control a machine. The machine's physical layout allowed 24 objects, but when the operators set it up for that it went berserk, because the 16 bit int was wrapping...
And no comments explaining what (and more importantly why) he was doing.
Best Slashdot Co
What are the mistakes I should not avoid?
If you use malloc() and free() you throw determinacy out of the window too. Is malloc() going to be a very fast tree search quickly returning an allocation of the right size? Is it going to be a slow tree search through fragmented memory returning an allocation? Is it going to require a system call (and is that going to be mmap() or brk()? Depends on your OS / malloc() implementation)? Is it going to be able to allocate from a thread-local pool or is it going to have to acquire a mutex and (potentially) stall other threads?
In hard realtime systems, dynamic memory allocation is not allowed for exactly these reasons. On most modern systems, the cost of handling a page fault is significantly more than the cost of scanning the nursery in a generational garbage collector, so you may not even get better performance from manual memory management, which requires you to be quite conservative about deallocation.
Good programming is about choosing the right level of abstraction for the problem at hand. Some programs require you to be close to the metal, others are best served by a very high level of abstraction, reducing the amount of code that you right (and, typically therefore, the number of bugs).
Good programmers are lazy, they like to solve a problem once and then forget about it. Saying that you would never use a particular tool is the sign of a terrible programmer - can you imagine a carpenter making the same claim? (I never use a hammer! Real carpenters always use a nail gun!)
I am TheRaven on Soylent News
I wish I could mod this up. There are two types of programmers, those that can take criticism and those who can't. The truly bad programmers don't want to hear it, and don't want to change anything. The other type are willing to listen, but cannot improve on their own; they need oversight to make them productive.
It also does not help when a large number of managers who are hired cannot do, more or less understand how, the work that needs to get done. Usually they don't want to get involved because they are busy in meetings being "productive".
The US should be the leader in IT, instead we want to ignore it because for a management, to get involved is too much like work. Everyone just wants to be paper pusher and makes life for programmers just hell because you can never get solid decisions on anything. If I had to start my career again, I would not get involved in IT; there are too many people who just have no idea what they are their doing and just pass the buck.
Your argument is silly, Super Programmer. In many cases you're not going to be the only person managing your code. Suddenly everyone else in the world is using strncpy() and you're using strcpy() just to be an ass, and you've got code with different conventions, one of which is just wrong (yours).
You must be coding facile code indeed to have written no extra code and to have handled strcpy() perfectly in every instance with 0 chance of error.
Please, please tell me you've coded something in the open source world so I can look at your code for 5 minutes, find an error, and laugh at you. Pretty please?
I'll tell you what, just to be an ass I'm going to start setuid root'ing all my programs whether they need it or not. What kind of incompetent programmer can't properly secure a program such that it can run setuid root, I ask you?
UI designed by programmer.
Yes: I'm looking at you, FOSS.
Or my favourite...UI's designed by graphic designers. I used to work with a fantastic designer. He had a real talent for creating visually appealing designs for our web apps that were simple and could be elegantly built with CSS but he insisted on putting menus and buttons in non-standard locations. The result was users had to relearn every interface and hunt for buttons. If we simply had OK, and Close buttons at the bottom right of dialogs, and the menus near the top right our programs would have been easier for new users.
When we migrated to C++ a while back, my biggest gripe became the number of projects, library, et.al. that weren't documented. I won't name the very popular library, but when I contacted the developers (I was still new with C++ at the time), they told me to "read the headers." Your code is not documentation, no matter how well you comment your functions. There's a subculture out there that I don't get that has the mindset that "it was hard to write, it should be hard to use" (and that's almost a direct quote from a library author). I don't know if it's job security, elitism, nepotism, or what. But, with some projects there's a cold disregard (borderline hostility) towards the people who will actually be using the product.
I swear to God...I swear to God! That is NOT how you treat your human!
There's one huge difference that makes programming different from engineering. Engineering is predictable - a mechanical, structural or civil engineer can accurately schedule the amount of time needed to produce a unit of work.
Programming isn't nearly as predictable - even the best developers I know can only schedule work to a tolerance of a couple of days. Invariably something turns out to be harder (or easier) than it was originally planned.
I think you overestimate the predictability of the engineering disciplines.
huh? there's all sorts of problems that have been solved by engineers where I'm certain the engineer went into the situation without a clue of exactly how they were going to solve the problem...and thus no idea exactly how long it would take. Engineering is only predictable in the sense you say if the problem being solved is one which is relatively common. But if you're, say, engineering a novel new bridge, there's a whole host of problems which aren't "predictable".
Forget FOSS. Try Enterprise software. I've never seen more consistently bad and unusable software than anything designed for the "enterprise".
You are in a maze of twisty little passages, all alike.
I've taken over Java progress where everything was OOP'ed into hell (as in a bazillion classes more than was needed for the application)
So something like a typical Java library then?
You are in a maze of twisty little passages, all alike.
or he has no idea what programming is. I can guarantee a lot of programmers are not doing "engineering" and most aren't doing "science", but as a whole programming software has a lot in common with those fields.
One of my favorite professors, I had him for calculus, physics, and programming, used to say to solve some of the problems in the classes he taught being creative would be helpful. Sometimes a problem had to be looked at in a different way, coming from a different angle.
Falcon
Should there be a Law?
TFA links to 7 programming languages on the rise, print version.
"I'm going to write this whole thing in Python or Ruby" simply because it's the latest "cool" language.
TFA above has this piece: "There seems to be two sorts of people who love Python [7]: those who hate brackets, and scientists. The former helped create the language by building a version of Perl [8] that is easier to read and not as chock-full of opening and closing brackets as a C descendant."
You should choose the language based on what will best do the job, not based on what's popular today, and you should choose one language for the entire project before you start writing the first line of code.
But what if a project is large and different sections are best written in different languages? With modularity a project can be broken down into different modules then the appropriate language can be used for each module.
Falcon
Should there be a Law?
We've come a long way from when hackers tried reduce the size of programs, however we've lost a lot along the way. Hell, to be a hacker as those in MIT's Tech Model Railroad Club was to be along the best programmers. Now a hacker is someone who's looked at a criminal.
Better checking for null in one common place and let the process fail gracefully than to check for nulls in the multitude of places that call this function.
That's a hacker routine, reducing the number of lines a program takes up. However that's not "fast and loose" programming.
Falcon
Should there be a Law?
Probably true. But for the vast number of jobs an engineer does, the work is very straightforward.
If I'm an architect and I want to know if my design is structurally sound, I know that I can hire a structural engineer for n hours of work and they'll be able to answer my question - and the number n is pretty much the same for all structural engineers. I'm not aware of any software engineers (and I am one) who schedule work by the hour (they may bill by the hour but they don't schedule by the hour).
That may be. I'm just parroting back what I was taught in college in my software engineering course. I've never worked as a mechanical or structural engineer.
But I do know that much engineering work is pretty-much cookie-cutter work.
f we simply had OK, and Close buttons at the bottom right of dialogs, and the menus near the top right our programs would have been easier for new users.
If you use Windows but not all Linux distros or OSX is laid out the same. Heck, they can even be customized to work the way the users wants them, within certain areas. I use OS X and Ubuntu now but when I used Windows I even rearranged it's layout.
Falcon
Should there be a Law?
Just wanted to point out that this doesn't apply in all languages. When dealing with languages where int i; does initialize to a known value, it's unnecessary (though not wrong) to do int i=0;. For example, most languages that aren't C or C++. If you're coding in Java, you know that if you do int i; it will be initialized to 0 for you.
What you are saying is of course factually correct. However, I disagree with the conclusion that just because a language does something you shouldn't also try to make you intentions as clear as possible.
Any developer worth his salt will program in a variety of languages over his career, with each language having its own semantics, conventions, and quirks. In my opinion, becoming a great developer is about cultivating a certain mindset. A great developer develops bulletproof habits, hard-won conventions learned across all programming languages.
In Java you don't have to initialize variables because the language defines semantics for that situation. It's technically not wrong, and a developer who chooses to recognize this and not initialize their variables is a not necessarily a lazy or bad developer, but it would raise my eyebrow. This leads to developing a bad habit which will bite you when you go to another language with different semantics, and your newly-declared int gets set to whatever trash value was lying around on the stack. It's all about the mindset.
Hey, Windows users, there is no such thing as "forward" slash, there is only slash and backslash.
Thank you, Firefox, for blocking them.
The comments here on Slashdot are far, far more useful than the original article, which I found to be rather trite and derivative ("don't do X. don't do ~X").
What are Mr. Peter Wayner's credentials? Sounds like he hasn't touched a single line of code in his life--even the examples won't compile and don't do the same thing that he says they do.
Try the the above "business logic is embedded in the code" when you're working for a company that is trying to sell a system to another customer. The developers then complain that Project X for customerX should do things the same way as Project Y for customerY did it. When you patiently explain that that's not how customerX do things, the development team then look at you as if you're an idiot. When your customers are government agencies, then you know there is a world of pain ahead for you and the development arm of the company you work for.
try maintaining code written by an architect
Isn't that some sort of racism? There are good architects, and there are bad architects.
Programmers, who want to characterize themselves as artists or craftsmen, are just too lazy to put in the engineering time. (Although, they do end up spending more time patching, fixing, and refactoring.) They don't want to document their requirements assumptions, provide adequate design documentation for reuse by other parties, be measured against their peers, and capture lessons learned by others. They tend to point to heavy-handed software management (another seriously delusional bunch) techniques as proof that the aforementioned doesn't work. The software industry as a whole needs a serious wake-up call, which will probably come from the rising amount of litigation, spawned by poor practices. The beauty of art is subjective, but software correctness is subject to scientific measurement.
Time is one of the best teachers. Better than peer review, better than cleaning code. Write your own code then come back and look at it in 3 or 4 years. It becomes pretty obvious how clean the code is, how easy it is to follow or how well it is documented. If you go to college, in the last 3 months you should be required to review, document, and modify software you have written over the past 4 years. I am afraid at the pace crap is thrown at you in school, most would not have time to appreciate the lesson it would teach them.
vi +
As long as you follow PMS Programming standards you are fine. Most depends on you situation, most places don't have the budget to do things the "Best Way"
Suddenly everyone else in the world is using strncpy() and you're using strcpy() just to be an ass, and you've got code with different conventions, one of which is just wrong (yours).
If someone can't use strcpy(), he should not program in C. Avoiding "dangerous" functions will not make his code better, it will just wrong in some other manner because.
Please, please tell me you've coded something in the open source world so I can look at your code for 5 minutes, find an error, and laugh at you. Pretty please?
Current uClibc MicroBlaze port and various Linux drivers. Now go, fuck yourself.
Contrary to the popular belief, there indeed is no God.
I'll tell you what, just to be an ass I'm going to start setuid root'ing all my programs whether they need it or not. What kind of incompetent programmer can't properly secure a program such that it can run setuid root, I ask you?
If program has to run in a non-MMU environment, this is exactly the case, as protections won't work there.
Other than that, programmer SHOULD always write software in a manner as if it will be safe to run setuid root. It should not actually be setuid root just in case that programmer might be wrong in some nontrivial manner -- there are plenty of ways to mess up security, and buffer overflow is only one of them, and easiest to avoid.
However if programmer can't calculate the size of his buffers, he is fundamentally incapable of writing any software that deals with buffers, and particular functions have nothing to do with it.
Contrary to the popular belief, there indeed is no God.
I love that and have been saying it for years. "All things in moderation, including moderation itself
Falcon
Should there be a Law?
Software engineering is slowly earning the title.
The reason that other types of engineers are better able to schedule jobs is the jobs have all been done many times before and the process, though complicated, is well understood.
As software engineers (as a group and as individuals) gain experience we are able to better schedule jobs.
I can schedule by the hour, but only for very small jobs.
My scheduling error is typically a % (which as I say varies based on risk, which varies based on many factors) of total job time, so if the total job is 40 hours I can pretty well say it won't take over 48 or less then 32 (I use +-20% as typical, tight specs, known tools.).
Of course if the client doesn't know what they want all bets are off. That's true for every type of engineer.
If an architect is breaking any new ground with their design you can bet the structural engineer will need more time and not be able to tell you exactly how long it will take.
I don't know where you got the idea that all engineering work outside software is 'very straightforward'.
All engineering is by its nature about trade-offs, is iterative and has no single 'correct' solution. (which isn't to say that there aren't incorrect solutions.)
Engineering is the union of applied science, business and art.
Nothing with that much to it can be called 'straightforward'.
John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
Furthermore, by not initializing variables, you are creating a special case for certain values. You are saying, in effect, "I will initialize variables to the correct value, unless that correct value happens to be [0|''|null]".
But I'd also argue that initialization doesn't have to occur at declaration. Constructors/factories/initializer methods are perfectly valid places for initialization.
Last post!
I'd modify this to say "always, always, always have a peer-review process". Junior devs are prevented from checking in crap because it gets caught by senior devs. The junior devs also learn quality habits from reviewing senior devs' code.
Though not the same when new programmers in school have asked on Slashdot how they can get experience or contribute to open source one bit of advise given is to pick an open source project then take one of the bugs listed as needing to be fixed. Then after a programmer has submitted some bug fixes they may be accepted as a contributor.
Falcon
Should there be a Law?
These are violently unsafe functions.
If those are unsafe, then dereferencing a pointer or using an array is unsafe, too -- and that means, a programmer is unable to write safe code no matter what.
You are just being stubborn for the sake of being stubborn. It's not about being unable to do your own buffer calculations. It's about using the tools available to you, to reduce the risk of making mistakes.
People do manage to make asses of themselves even with so-called 'safe' string APIs, but there's no good reason to not use them.
What?
The only kind of "safe" strings handling that I am aware of, is operations on strings that are combined with allocation (in object-oriented or almost-object-oriented way). Their purpose is to simplify common operations, any "safety" is at best a side effect that shouldn't matter if programmer is not a moron in the first place.
Hence the words "so-called"...
Strcpy()
strcpy()
Case-sensitive names should be written as they are defined, no matter where they are in a sentence.
What kind of pedantic asshole insists on capitalization on a message board, but refuses to see the basic sense in using functions that give you a little help?
or strcat() have pitfalls that are really esoteric, and if you keep using them you'll eventually make a mistake and end up with some absolute motherfucker of a bug with security ramifications you wouldn't even have imagined.
I repeat -- if you can mess up strcpy(), you can mess up anything, and should not be allowed to write any code to begin with. It does not matter how many opportunities you are given to jump in front of a bus or a train -- what is important is that you should not do it.
Get off your high-horse. Even the most elite programmers make mistakes.
That's true actually.. the automated stuff should just be part of your post-build process, the guy writing the code gets immediate feedback on completing a build and fixes that crap before asking for a peer review.
You still need to run a build (and post-build verification) as part of a code review, to account for differences (if any) between your dev environments. Ideally there should not be any, but we know how that works. The most time-efficient way (on big projects) is to kick of the build so it can do it's thing, and then the post-build tools can do their thing, while you're reading code.
Same with my job - EE.
I work with computer boards and firmware (i.e. VHDL coding) and it's just the same. Like today: 10 hours and all I accomplished was four tests (instead of the planned ~50), because there was a problem in the wiring & finding the "bug" was difficult. Even now I'm not certain what the problem was, but I did eliminate it (removed the part and white-wired).
So yeah - engineering can be just as unpredictable as programming.
"I disapprove of what you say, but I will defend to the death your right to say it." - historian Evelyn Beatrice Hall
Did you just use "irregardless"???
Yes. I always liked The Far Side cartoons.
Forget thrust, drag, lift and weight. Airplanes fly because of money.
my rule is: if in doubt, choose C. It's still in heavy use after almost forty years for a reason.
Now I'm working on the book Learn C on the Mac. As I said in another post most of what's taught in college now, and has been for years, is Windows. I need a refresher for C and C++, though I'm thinking of working on Objective C next, and because I'm using a Mac now I thought I'd try that book. Then I want to get a book on C programming on Linux, I have a Linux PC I want to set up as a server and I want to dual-boot my laptop.
You can justify it all you want from a code readability perspective, but the fact remains that it leads to really awkward coding practices, like indenting function bodies sixteen spaces just in case you need to add another nesting level.
I have trouble reading code that isn't indented and nested. Of course I don't read much code and if I did I might get better. Then again there's a lot to be said about readability.
It brings back memories of BASIC and line numbering every ten lines.
I first programmed use line numbers for every line, of course they were numbered 10, 20, 30. I was shocked the first tyme I saw a BASIC listing that was not numbered every line, I thought there was something wrong with the listing.
Falcon
Should there be a Law?
Really slowly. Let us know when software "engineering" has the equivalent of Building Codes and the head Enginner signs the document that makes them personally and legally liable for any wrongdoing at each code release/something new built. Coders have always wanted the "engineering" title without the engineering discipline.
+++OK ATH
The job of a structural engineer is to analyze a design and render opinions about the amount of stress a particular structure can withstand and to design structures which can resist particular loads. In the context I described (an architect designing a house), you're right that a part of their job is similar to that of a tester.
While it's true that you really shouldn't be managing the pointers and memory allocations yourself due to the chance of introducing nasty bugs there is quite a lot to be said for knowing HOW to do so.
Not a sentence!
strncat(), when applied to unexpectedly long string, unpredictably alters the data the program processes. Formally, that's just as insecure as running arbitrary code -- it just happens that for some software standards are so low, altering the data (producing garbage) is "more acceptable". The only thing this condition describes is the sorry state of software industry.
As for programmers making mistakes, the rate of mistakes made by every programmer at his skills level is constant and unalterable by his tools. If he isn't given an opportunity to miscalculate a buffer size, he will fill his quota by making a more fundamental error with just as disastrous consequences but without a "recipe" to fix. The only way to improve is to constantly pay attention.
Contrary to the popular belief, there indeed is no God.
i think you mean discrimination, last time i checked architects arent a race.
also, this guy is a good architect, and that is the entire problem, he is so caught up in architectural purity and abstractions (and it all makes sense too) that his code has gotten so complex that it is near-impossible to understand without weeks of specific training
People, what a bunch of bastards
Oh, I'd never claim otherwise! It's just that there are precious few times when I've ever actually needed to do that stuff myself for reasons beyond "because the language won't do it for me".
Dewey, what part of this looks like authorities should be involved?
Garbage collection is for little boys.
So, only men create memory leaks?
quote>strncat(), when applied to unexpectedly long string, unpredictably alters the data the program processes. Formally, that's just as insecure as running arbitrary code
How so??
This captures the essence of our disagreement.
Altering data by inadvertently truncating a string is bad, and buggy -- absolutely -- you gotta do the work to validate your data beforehand to that doesn't happen. Absolutely. You're saying constantly pay attention, etc. etc. -- here's where you do that. Validate your data when it crosses trust boundaries, and use the right string functions, that *tell* you when your buffer was too small and your data got truncated, and handle that correctly in your code. I don't quite understand why everyone points out strncat() at the drop of a hat as if that's your only so-called safe option (it isn't, and it's only a slight improvement on straight up strcat).
My #1 mistake to avoid is simply "Not understanding the layer beneath the layer you are programming in." It's nearly impossible to code something right if you don't understand at least the layer immediately beneath the one you are programming in, so you can understand how to use it properly to get your work done, and don't try to (inefficiently) re-implement stuff that is already handled in the layer below.
You see? You see? Your stupid minds! Stupid! Stupid!
Almost there in aviation.
Asked back: Are all engineers 'personally and legally liable' for any mistakes they make?
Can software engineering earn the title short of structural engineering type sign offs?
Do you think the people that engineered the Parthenon were not engineers because they were still figuring out how to build with 'crete and didn't follow building codes?
John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
I'm just sayin' some Engineers work a lot harder for the title than others. Let me know when there's a PE certification for software. ;-) Software seems to be one of the areas where prima-donnas really like the title, and then bloviate endlessly online about how it's not a science-only, or a tech-only position, but it requires "Art". In the Civil Engineer world, the "Art" is handled by the Architect. The Engineer makes sure the damn thing doesn't fall on anyone's family. And there are TV shows about when they screw up... called "Disasters". I've seen some true software disasters in my time in Tech Support roles, and never once seen a TV show about them... because they happen consistently and every day, the world over. Thus my observation that "Software Engineering, isn't." At least, not yet. Not even close. :-)
+++OK ATH
Lack of experience is certainly one way it can happen. In other cases, what was once a small simple app finds itself used well beyond it's design life and outside it's design parameters. Somewhere in there it needed a re-factoring at least and probably a re-design to fit it's new larger role, but it gets nixed since it's "good enough for now". Lather, rinse, repeat and suddenly it's a horrible mess.
In still other cases, expectations out of line with reality cause the problem. The app is supposedly going to be HUGE, running on a farm of thousands of servers with a million users each of which will create hundreds of pages. A year later, the 4 page app with 12 users running on the re-purposed desktop machine looks awfully over-designed.
It's even harder to get the OK to pare a program down to an appropriate scale. The natural evolution then is that more and more additions bypass large segments of it until it becomes the little program struggling to get out of the big pile of baggage all around it.
Use static analyzers when you're done with the "human" aspect of the review
No do it before, you will save everyone time
Jehovah be praised, Oracle was not selected
This captures the essence of our disagreement.
No, it does not.
Altering data by inadvertently truncating a string is bad, and buggy -- absolutely -- you gotta do the work to validate your data beforehand to that doesn't happen. Absolutely.
You can validate something "you" received from someone or something else -- in other words, across an interface. On the other side of this interface there can be something written with a wrong assumption of your code's parameters such as size of the buffer (or plenty of other equally important properties of your code that may be equally important for security). It may be someone else's code or your code, but if you have an interface with any nontrivial restriction on data, such as size, you can assume that whatever is on the other end may be wrong and should be checked -- this is a part of well-known rule about producing strictly defined output and being able to process loosely defined input.
On the other hand, you can absolutely not validate something you have just done yourself -- if you are wrong in one place (when you generated a string and presumably allocated a buffer or checked that result of your operation can fit in buffer you have) you can just as well be wrong in another place (when you given a number of strncpy() that you believe is the size available for copying). Strings don't get copied between buffers allocated just for them -- that's stupid, and this is what either passing a pointers (so nothing has to be allocated or copied) or strdup() (so allocation is guaranteed to be right) is for.
Strings are copied to produce strings, packets, binary file pieces, etc. from chunks of other strings -- in other words, as a part of text manipulation that can be simple or complex. This means, you still have to somehow determine how much space is available in your destination buffer when you copy this particular string, as your destination is likely the end of some other string or data structure. If you have to produce this number to stuff into your strncpy() function argument, you can be right, but just as well you can be wrong. Doing it multiple times just gives you more opportunities to be wrong.
On the other hand, calculating the size of the buffer when it is being allocated, or some when large, possibly complex, but predictable operation is started -- so it will not be possible for you to be wrong again -- is one calculation. Once you have passed this hurdle, you can be safe that your subsequent parts of this operation will not be able to overrun this buffer. Trying to "verify" that fact again will just fill your program with meaningless numbers -- constant or calculated. They will not make you safe. They will be multiple places that you will have to check and modify when you make any changes to your code. It is completely useless, and only hurts your security by making your code fragile. This is how secure and insecure design works. Not by calling "secure" functions or second-guessing calculations you have already done.
I don't believe, I have to explain those things to someone who supposedly understands what strcpy() is. No wonder, there is shit code everywhere.
Contrary to the popular belief, there indeed is no God.
they won't have to scale and extend the way they think they might
Wow, talk about short sighted.
Good design is important for maintainability and scalability, yes. But it's *FAR MORE* important for testability.
Abstract classes, interfaces, etc, encourage loose coupling between code, and *that* leads to code that's unit testable. It *also* happens to produce code that's generally modular, extensible, and easily refactored. But that's just a pleasant side-effect.
In short, simple is good. Simplistic is not.
This captures the essence of our disagreement.
No, it does not.
Sure, whatever, tough guy..
I don't believe, I have to explain those things to someone who supposedly understands what strcpy() is. No wonder, there is shit code everywhere.
Listen child - first of all, you keep referencing strncat/strncpy as if it's your only (so-called) safe string function available. Search harder son. The issue you called out, is the reason strncpy is a terrible example of a safe-string function -- but apparently you stopped there and came to a prematue conclusing instead of researching the issue the end, and you also decided you're a superprogrammer with all the answers. I'll leave the discovery of 'safer' functions to you as an exercise, mostly because the answer is platform dependant. Sometimes you might actually not have something better than strncat, so you end up having to roll your own. I'll leave the exact nature of the 'roll your own' function to you as an exercise as well, because in the process of figuring out what it should look like (or if you research a little and emulate something better than strncpy) you'll become a better coder.
This could have been a cordial conversation. Informative even. But you chose to be an asshole/internet tough guy. Do yourself a favor and research the topic a little. You have a glaring hole in your knowledge here, and I guarantee you within about 2 hours of reading you'll understand just how bad it is.
On the other hand, calculating the size of the buffer when it is being allocated, or some when large, possibly complex, but predictable operation is started -- so it will not be possible for you to be wrong again -- is one calculation. Once you have passed this hurdle, you can be safe that your subsequent parts of this operation will not be able to overrun this buffer.
Just to give you a hint along your research -- you're thinking along the right lines here. You merely need to expand on this thought a little, and you can come up with a 'safer' string function that takes advantage of this known-to-be-corret buffer size.
Next time, check your fucking ego at the door.
When you work it all the way down, most code issues are about the money. Companies sell code to make money. They want to pay as little as possible to produce it. And make as much as possible from it. Bad coders, ignorant coders, lack of testers, bad testers, ignorant managers, lack of processes -- all of it. Bad coders have jobs because companies only want to pay so little that only bad coders take the money. Ignorant coders of course are paid little. Testers cost money -- so hire as few as possible or have the bad ignorant coders test their own code. Hire/keep potted plants as managers because they are cheap. Take the money and run. Ultimately this is the root cause of it all. And it will never change. This is the way it was 30 years ago. This is the way it is today. This is the way it will be 30 years from now.
Now you know. And the Art of which you speak isn't about looking pretty, it's about being able to see the cleverly simple way to cleanly solve the problem at hand. It's an Art which isn't restricted to software, and it's most certainly not solved by architects. I'd equate the building architect to part of the requirements gathering process...then it's up to the civil engineer to find a way to meet the requirements (i.e., construct the damn thing such that it won't fall down).