Code Neatness
-
I am already using two monitors, so I am talking about REALLY long lines! :-D
-
Ravi Bhavnani wrote:
If the code loops a million times, I think we have a much bigger problem.
Usually the problem that requires millions of iterations in it's solution :-D Search engine query? How many hash buckets would you need to eliminate child node searches altogether? "grep"ing a large text (or set of) files. SQL query on a large database (somebody's got to write the query engine!) Sure, these are examples of stuff that typically has a multitude of pre-existing, mature solutions but a) they're just examples to show that there are domains where millions of iterations can be reasonably expected b) Somebody's got to maintain it!
T-Mac-Oz
The good practice is “Lazy Evaluation” – declaring as late as possible, and keep it within the scope only (hide it from outside). If you declare everything in the beginning of a function, you probably will forget to clean up the residual data before using it.
-
AmazingMo wrote:
Try it a million times or so and see what happens.
If the code loops a million times, I think we have a much bigger problem. :)
AmazingMo wrote:
most compilers will hoist the variable declaration out of the loop scope, but do you want to take the risk that the particular compiler that you're using will?
[edit] I can't imagine I'd use one that didn't do that as part of standard optimization! Code hoisting has been around for decades and is pretty mature technology. [/edit]
AmazingMo wrote:
You started programming in C, didn't you
No. I started programming before the first mainstream C compilers came to market. /ravi
My new year resolution: 2048 x 1536 Home | Music | Articles | Freeware ravib(at)ravib(dot)com
modified on Monday, March 10, 2008 2:17 AM
Ravi Bhavnani wrote:
can't imagine I'd use one that didn't do that as part of standard optimization! Code hoisting has been around for decades and is pretty mature technology.
If the object has a constructor or destructor, the C++ standard requires that it is destroyed and a new object created on every iteration of the loop. But the compiler will construct the object in the same space each time.
DoEvents: Generating unexpected recursion since 1991
-
So somewhere on the internet, I pointed out to a newbie that his code was pretty messy and that he should start by consolidating some of his variable declarations to the beginning of the program (which was consisted of only a main(…) function/method/entry point and a lot of improperly formatted code). In walks another forum member and criticizes me for my comment saying that "it's a feature of the C++ language to be able to declare variables anywhere you need it." I was obviously pissed at that comment showing his utter disregard for code neatness and readability (and likely a malicious attack on my intelligence). I'm trying to seek agreement… so was I right when I said so?
So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?
Here's a free site for cleaning up your SQL...just paste your code in it and hit the Prettify! button.... www.simple-talk.com/prettifier/
-
AmazingMo wrote:
Do you still use Hungarian notation? Some times it's better to just let go.
The original concept of Hungarian Notation was actually quite different from M$s butchery of it. I forget the actual words used to define the concept but the prefix was really meant to indicate the usage of the variable, not its data-type. E.g.
//M$: DWORD dwVar1, dwVar2; // M$ uses prefix to denote type // not very useful in the grand scheme of things, // since the compiler picks up type mismatches // What is the variable used for? // You have to scan the code to find out for (dwVar1 = 0UL; dwVar1 ... { for (dwVar2 = 0UL; dwVar2 ... //Original Hungarian: DWORD outerIterVar, innerIterVar; // Original Hungarian uses prefix to denote usage (e.g. "outer iterator"), // giving the programmer an idea of the intended usage of the variable // without having to scan the code for (outerIterVar = 0UL; outerIterVar ... { for (innerIterVar = 0UL; innerIterVar ...
Having worked with MFC and WinAPI for so many years, it came as a surprise to learn this but I saw the sense in it right away & have tried to "do it properly" ever since. Unfortunately, old habits die hard... sigh.T-Mac-Oz
Larry Osterman and others have documented that Hungarian Notation originated with Charles Simonyi in the apps group at Microsoft. It was the systems group that bastardized it to the form we see in Windows where the syntactic type, which can be checked by the compiler, is encoded in the name. (Someone from the systems group, who was blamed by Larry for the error, here[^] claims that it was the people who authored the documentation that screwed it up!) I think true Hungarian would have called your variables iOuter and iInner, where the i prefix indicates an index into an array, but of course the problem is that i has been overloaded in "Systems Hungarian" (or "Anti-Hungarian" as Rick Schaut calls it[^]) to mean 'int'.
DoEvents: Generating unexpected recursion since 1991
-
Shog9 wrote:
Do people not know how to generate assembler output from their compilers anymore?
Nope. And if they did can they read it?
A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects. - -Lazarus Long
Funnily enough I was looking at JIT output last night! How do I see what the JIT compiled, anyway?[^]
DoEvents: Generating unexpected recursion since 1991
-
So somewhere on the internet, I pointed out to a newbie that his code was pretty messy and that he should start by consolidating some of his variable declarations to the beginning of the program (which was consisted of only a main(…) function/method/entry point and a lot of improperly formatted code). In walks another forum member and criticizes me for my comment saying that "it's a feature of the C++ language to be able to declare variables anywhere you need it." I was obviously pissed at that comment showing his utter disregard for code neatness and readability (and likely a malicious attack on my intelligence). I'm trying to seek agreement… so was I right when I said so?
So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?
Declaring variables at the top of a function or program is bad idea. Consider the following:
void function()
{
int i;// use 'i' for purpose 1 ... // use 'i' for purpose 2 ... // use 'i' for purpose 3 ... if(i == 14) { // crash the program }
}
At the bottom of the function, 'i' is the accidental work product of the last place that it was used. Suppose this function is 200 lines long? Is the user supposed to hand examine every single place a variable is modified in order to understand what its value is currently being used for? Instead, declare variables as close to the point that they are actually used and make sure that they go out of scope as quickly after that as possible to reduce confusion to later maintainers. Confusion is the root of all evil in s/w. Lowell used.
-
I am already using two monitors, so I am talking about REALLY long lines! :-D
mhaines@1amadeus.com wrote:
I am already using two monitors, so I am talking about REALLY long lines!
so use two 30" monitors.... come on, use it as an excuse... you know you want them!
_________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
-
So somewhere on the internet, I pointed out to a newbie that his code was pretty messy and that he should start by consolidating some of his variable declarations to the beginning of the program (which was consisted of only a main(…) function/method/entry point and a lot of improperly formatted code). In walks another forum member and criticizes me for my comment saying that "it's a feature of the C++ language to be able to declare variables anywhere you need it." I was obviously pissed at that comment showing his utter disregard for code neatness and readability (and likely a malicious attack on my intelligence). I'm trying to seek agreement… so was I right when I said so?
So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?
Ri Qen-Sin wrote:
I'm trying to seek agreement… so was I right when I said so?
yes, and no. If your code loops or branches, it matters where you declare your variables. For instance declaring all your variables up front pulls a lot of space off the stack or heap, creates overhead, and if you branch or exit early, you have created unnecessary overhead. If your code branches with an if or a switch, you never want to incur the overhead associated with unused branches. on the other side, declaring a variable inside of a loop means that this variable will be allocated and deallocated often. By moving the declaration outside of the loop, your cost is significantly less performance wise. BUT! The rule above still applies. You do not have to move it to the front of the function, though you can if you don't branch or exit early.
_________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
-
Also, in addition to above comments, declaring variables at the top could stem from variable name re-use in C, C++: So at the top of a function you'd have: int i, j; Then you could re-use those variables in your function multiple times and the memory would only be allocated once. for (i = 0; i < blah, i++) { for (j = 0; j < blahblah; j++) do something; } for (i = 0; i < blah, i++) { for (j = 0; j < blahblah; j++) do something else; } In todays languages it would be: for (int i = 0; i < blah, i++) { for (int j = 0; j < blahblah; j++) do something; } for (int i = 0; i < blah, i++) { for (int j = 0; j < blahblah; j++) do something else; } ... but if you try that in C++ you get a duplicate definition error on i. Just trying to justify declaring variables at the top, I don't think there's a right or wrong way. Personally, I declare them as close to the point of use, as other people have mentioned, but if they're generic, reusable index variables I do them at the top. Then again, I'm old school. Compilers optimize this stuff for us now, but it's a hard habit to break. In my head, defining int j inside another loop will cause a memory allocation each time through the first loop. Ramblin' on....
- S 50 cups of coffee and you know it's on!
Steve Echols wrote:
but if you try that in C++ you get a duplicate definition error on i.
That was just MS. Other compilers don't have that problem, though as mentioned MS can fix it with an option.
_________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
-
Ri Qen-Sin wrote:
so was I right when I said so?
No. C required you to declare variables at the beginning of a function, because C (and C++) allocate all local variables when the stack frame is being constructed, and it simplified the compiler. C++ doesn't require this. Making me scan back through your code looking for a variable declaration isn't being neat. It's just being rude. I actually had to explain this to a new consultant last week, when he tried to argue that throwing a dozen variable declarations at the top of a rather large function increased efficiency by avoiding allocations in a loop. Good grief. Do people not know how to generate assembler output from their compilers anymore? :suss:
Shog9 wrote:
Good grief. Do people not know how to generate assembler output from their compilers anymore?
No, most do not.... :sigh: :sigh:
_________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
-
Ravi Bhavnani wrote:
can't imagine I'd use one that didn't do that as part of standard optimization! Code hoisting has been around for decades and is pretty mature technology.
If the object has a constructor or destructor, the C++ standard requires that it is destroyed and a new object created on every iteration of the loop. But the compiler will construct the object in the same space each time.
DoEvents: Generating unexpected recursion since 1991
-
Matter of preference, really, as long as you don't declare inside a loop... but, yeah, I generally put them at the top if the method is not long. Otherwise, I group them in blocks near where they are used...
Odd comment - I've found that for managed code (somewhat common these days), if I declare outside the loop and load the values into a containers (e.g., ArrayList), they all have the same value when I'm done. Now, If I declare inside the loop, each is a newly created version and it works as expected. Roughly speaking: This will work as expected ArrayList ^tmp = gcnew ArrayList(); for(int i=0;iLength; ++i) { Object ^x = ContainerFullOfObjPtrs[i]; tmp->Add(x); } This is usually somewhat disappointing ArrayList ^tmp = gcnew ArrayList(); Object ^x = gcnew Object(); for(int i=0; i; Length; ++i) { x = ContainerFullOfObjPtrs[i]; tmp->Add(x); } "The difference between genius and stupidity is that genius has its limits." - Albert Einstein "How do you find out if you're unwanted if everyone you try to ask tells you to go away?" - Balboos HaGadol
-
So somewhere on the internet, I pointed out to a newbie that his code was pretty messy and that he should start by consolidating some of his variable declarations to the beginning of the program (which was consisted of only a main(…) function/method/entry point and a lot of improperly formatted code). In walks another forum member and criticizes me for my comment saying that "it's a feature of the C++ language to be able to declare variables anywhere you need it." I was obviously pissed at that comment showing his utter disregard for code neatness and readability (and likely a malicious attack on my intelligence). I'm trying to seek agreement… so was I right when I said so?
So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?
Since it was your opinion, it was neither right nor wrong.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
AmazingMo wrote:
Do you still use Hungarian notation? Some times it's better to just let go.
The original concept of Hungarian Notation was actually quite different from M$s butchery of it. I forget the actual words used to define the concept but the prefix was really meant to indicate the usage of the variable, not its data-type. E.g.
//M$: DWORD dwVar1, dwVar2; // M$ uses prefix to denote type // not very useful in the grand scheme of things, // since the compiler picks up type mismatches // What is the variable used for? // You have to scan the code to find out for (dwVar1 = 0UL; dwVar1 ... { for (dwVar2 = 0UL; dwVar2 ... //Original Hungarian: DWORD outerIterVar, innerIterVar; // Original Hungarian uses prefix to denote usage (e.g. "outer iterator"), // giving the programmer an idea of the intended usage of the variable // without having to scan the code for (outerIterVar = 0UL; outerIterVar ... { for (innerIterVar = 0UL; innerIterVar ...
Having worked with MFC and WinAPI for so many years, it came as a surprise to learn this but I saw the sense in it right away & have tried to "do it properly" ever since. Unfortunately, old habits die hard... sigh.T-Mac-Oz
As I recall, the way I learned Hungarian notation was developing for the mac in C++, we would use "m" to denote a member variable (eg. mUrl), and maybe "p" for a parameter, etc. Typesafe languages don't need the type as a prefix, but often there is some conflict between what kind of a variable you're using.
“Time and space can be a bitch.” –Gushie, Quantum Leap {o,o}.oO( Want a great RSS reader? Try FeedBeast! ) |)””’) -”-”-
-
So somewhere on the internet, I pointed out to a newbie that his code was pretty messy and that he should start by consolidating some of his variable declarations to the beginning of the program (which was consisted of only a main(…) function/method/entry point and a lot of improperly formatted code). In walks another forum member and criticizes me for my comment saying that "it's a feature of the C++ language to be able to declare variables anywhere you need it." I was obviously pissed at that comment showing his utter disregard for code neatness and readability (and likely a malicious attack on my intelligence). I'm trying to seek agreement… so was I right when I said so?
So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?
I have been programming since 83. I have worked with a whole slew of languages and OS's and I have come to some really hard fought conclusions. First of all, whatever coding standard you implement, be consistent. That way if you discover a problem with the way you are doing things, it will be consistently wrong. I recently ran into a problem that was extremely difficult to track down but it was resulting in a stack corruption. After many hours of going bleary eyed trying to read my over 500,000 lines of code I resorted to a third party code checker. One of my problems was the 'just in time' variable declaration approach. I never expected to find that if you declare a variable within a code block such as an if or a switch that the variable would go out of scope later on. While this was not my only problem it did contribute to my issue. Secondly, I have had many programmers working for me over the years and have found that the KISS principle really applies here. If I allowed my programmers to code any way that they want, I can't support the code. If I insist that the coding, variable declarations, variable naming convention etc all be done in a certain way, then it can be maintained by multiple programmers. For this reason alone, I am an ardant supporter of declaring variables at the top of a function. You may be asking how I ended up with JIT declarations then? Simple answer, other peoples code. 'With hurricanes, tornados, fires out of control,mud slides, flooding, severe thunderstorms tearing up the country! from one end to another, and with the threat of bird flu and terrorist attacks, are we sure this is a good time to take God out of the Pledge of Allegiance?' - Jay Leno
-
Ri Qen-Sin wrote:
so was I right when I said so?
No. C required you to declare variables at the beginning of a function, because C (and C++) allocate all local variables when the stack frame is being constructed, and it simplified the compiler. C++ doesn't require this. Making me scan back through your code looking for a variable declaration isn't being neat. It's just being rude. I actually had to explain this to a new consultant last week, when he tried to argue that throwing a dozen variable declarations at the top of a rather large function increased efficiency by avoiding allocations in a loop. Good grief. Do people not know how to generate assembler output from their compilers anymore? :suss:
Just because there is a new feature doesn't mean it's necessarily better. There have been mistakes made in the past with "new features". In this particular case, however, I agree with you.
“Time and space can be a bitch.” –Gushie, Quantum Leap {o,o}.oO( Want a great RSS reader? Try FeedBeast! ) |)””’) -”-”-
-
Does being hoisted on its own petard count?
Otherwise [Microsoft is] toast in the long term no matter how much money they've got. They would be already if the Linux community didn't have it's head so firmly up it's own command line buffer that it looks like taking 15 years to find the desktop. -- Matthew Faithfull
-
I have been programming since 83. I have worked with a whole slew of languages and OS's and I have come to some really hard fought conclusions. First of all, whatever coding standard you implement, be consistent. That way if you discover a problem with the way you are doing things, it will be consistently wrong. I recently ran into a problem that was extremely difficult to track down but it was resulting in a stack corruption. After many hours of going bleary eyed trying to read my over 500,000 lines of code I resorted to a third party code checker. One of my problems was the 'just in time' variable declaration approach. I never expected to find that if you declare a variable within a code block such as an if or a switch that the variable would go out of scope later on. While this was not my only problem it did contribute to my issue. Secondly, I have had many programmers working for me over the years and have found that the KISS principle really applies here. If I allowed my programmers to code any way that they want, I can't support the code. If I insist that the coding, variable declarations, variable naming convention etc all be done in a certain way, then it can be maintained by multiple programmers. For this reason alone, I am an ardant supporter of declaring variables at the top of a function. You may be asking how I ended up with JIT declarations then? Simple answer, other peoples code. 'With hurricanes, tornados, fires out of control,mud slides, flooding, severe thunderstorms tearing up the country! from one end to another, and with the threat of bird flu and terrorist attacks, are we sure this is a good time to take God out of the Pledge of Allegiance?' - Jay Leno
Timothy W. Okrey wrote:
I never expected to find that if you declare a variable within a code block such as an if or a switch that the variable would go out of scope later on.
Well this is simply a case of being uneducated about the rules of the language you were using. I could argue that I never expected:
int main( void ) { MakeAwesomeProgram(); }
...to not create the world's awesomest program, but chances are it's not going to. The rules of scope declaration are quite sound: a variable is only good in the scope it's defined in. In fact, you can even use a rarely-seen technique for defining arbitrary blocks of scope solely for this purpose:{ int i = 5; ... } { int i = 10; // different 'i' ... }
“Time and space can be a bitch.” –Gushie, Quantum Leap {o,o}.oO( Want a great RSS reader? Try FeedBeast! ) |)””’) -”-”-
-
Does being hoisted on its own petard count?
Otherwise [Microsoft is] toast in the long term no matter how much money they've got. They would be already if the Linux community didn't have it's head so firmly up it's own command line buffer that it looks like taking 15 years to find the desktop. -- Matthew Faithfull