-
Reinitializing variables & their speed sacrifice
My C++ teacher states that one should not initialize a variable at declaration time (yes i know who made her a teacher!?). Although I'm past the C# point, & VCL, & GDI in C/C++, I find this amusing & irritating at the same time.
so for the foll. code:
Code:
//It's C Code, so cant initialize 'a' inside loop.
int main()
{
int a=0,b=0;
scanf(...,&b)
for(a=0;a<10;a++)
...
return 1;
}
She says:
1. Why the hell use int main() when void main() works fine. Let's just not get started on her ignorance to good coding practices & her ignorance to OS's error handling. I just skip it thinking she's ignorant.
2. Why initialize b. When b is inputted. ***?
3. Why initialize a, when you reinitialize it in loop. *** x2?
OK, as we all know it's ALWAYS a good practice to ZeroMemory() or atleast initialize a variable to 0 or NULL. Her only case may appear a bit(0.001%) effective, if this practice poses a speed loss?
Only if assigning a=0 inside loop or declaring b=0 at initialization poses speed loss, then only her arguments might be only a bit(0.001%) effective, otherwise I'll declare war.
Can anyone tell if these practices do really pose a speed issue?
Thanks,
Nisheeth
-
Re: Reinitializing variables & their speed sacrifice
void main isn't legal C++. Some compilers let you get away with it, but it isn't legal.
Your teacher is right that initializing isn't always necessary, but if you get in the habit, you're less likely to forget to do it when it is necessary.
2 and 3, good question. She's right that it adds nothing.
Better question, why even declare a outside the loop. The only reason for that is if you need the scope to persist outside the loop. Sometimes you may, but not usually.
Back in the old days, programmers really did have to try really hard to optimize their code. The first system I worked on had 4 MB, that's megabytes of memory and 120 concurrent users. It was imperative to write small, tight, efficient code. These days it's still important, but you don't have to worry about the minutia the way we used to.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by nbaztec
//It's C Code, so cant initialize 'a' inside loop.
Incidentally, if you can use // to denote a comment, then it is C99 code, thus you can declare and initialise a in the init statement of the for loop :)
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
GCDEF
void main isn't legal C++. Some compilers let you get away with it, but it isn't legal.
Yes, I know this that's why I don't mind if she insists upon using void main(), coz I know I'm danm right in using int main().
Quote:
Your teacher is right that initializing isn't always necessary, but if you get in the habit, you're less likely to forget to do it when it is necessary.
2 and 3, good question. She's right that it adds nothing.
But isn't it that suppose I later on added another loop before the first one('a') or design a function (for 'b') it may pose some risk( I know I'll be the one responsible, but building a safe code is always good).
The same variables I use in many places, as we all know in programming Memory is everything. I mainly focus on reducing memory usage, avoiding time loss due to redundant looping & using Multi-threading(I know this doesn't fit here, but in VC++ I do it). And, I may be wrong, but isn't it always recommended to either ZeroMemory() or assign Null to variables. Even Default constructors do it. And we know that a default constructor is called anyway. So does it matter much is we assign values explicitly?
Even in C++ using try(), catch() throw may pose some speed losses but they make the code a lot more efficient, isnt it?
Quote:
Better question, why even declare a outside the loop. The only reason for that is if you need the scope to persist outside the loop. Sometimes you may, but not usually.
same for @laserlight
Dunno why but we use TC++, a clearly good but outdated compiler, that's prone to make memory leaks. I learnt it the hard way. The C file created lets you use the '//' Comments but the variables have to be defined at the start only, strange, but it throws error.
Quote:
Back in the old days, programmers really did have to try really hard to optimize their code. The first system I worked on had 4 MB, that's megabytes of memory and 120 concurrent users. It was imperative to write small, tight, efficient code. These days it's still important, but you don't have to worry about the minutia the way we used to.
By that I guess your a veteran programmer, and many times better than me. My respects. Thanks for replying. Highly Appreciate it.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
GCDEF
Back in the old days, programmers really did have to try really hard to optimize their code. The first system I worked on had 4 MB,
Is this going to be the start of a thread where all the oldies start bragging about how 'you had it easy mate' as they used to write applications by entering the instructions in binary via switches on the front panel :D
BTW You had it easy mate! I first started to program on a PDP11/04 with memory measured in a few kilobytes...
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
JohnW@Wessex
Is this going to be the start of a thread where all the oldies start bragging about how 'you had it easy mate'
BTW You had it easy mate!
lol...but a firm no. Well the times at which u guys programmed sure were....um...tight!
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by nbaztec
Yes, I know this that's why I don't mind she insists upon using void main(), coz I know I'm **** right in using int main().
As long as you know what is correct, then it does not really matter in an academic environment like yours. That said, you could show her the answer to this FAQ on Can I write "void main()"?, and casually point out that its author, Bjarne Stroustrup, College of Engineering Chair Professor in Computer Science at Texas A&M University, is the designer and original implementer of C++.
Quote:
Originally Posted by nbaztec
And, I may be wrong, but isn't it always recommended to either ZeroMemory() or assign Null to variables.
Taken literally, no. Zero initialisation is not always the most sensible thing to do, and in fact if you can follow the rule of declaring variables near first use, defaulting to zero initialisation should actually be an exception rather than the norm.
Quote:
Originally Posted by nbaztec
Even Default constructors do it. And we know that a default constructor is called anyway.
Whether a default constructor performs zero initialisation depends on its semantics and implementation.
Quote:
Originally Posted by nbaztec
So does it matter much is we assign values explicitly?
In the case where a variable will be immediately assigned to, initialisation for the sake of initialisation might confuse a reader - or it might not - thus it becomes a matter of style. But this is only if it is coupled with the rule that variables should be declared near first use, otherwise the initialisation becomes initialisation for the sake of defensive programming.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
nbaztec
The same variables I use in many places, as we all know in programming Memory is everything. I mainly focus on reducing memory usage, avoiding time loss due to redundant looping & using Multi-threading(I know this doesn't fit here, but in VC++ I do it). And, I may be wrong, but isn't it always recommended to either ZeroMemory() or assign Null to variables. Even Default constructors do it. And we know that a default constructor is called anyway. So does it matter much is we assign values explicitly?
I just bought a PC with 6GB of RAM for $409. RAM is cheap. You want to be careful, but if you're reusing variables rather than allocating a few extra ints, you're not programming well.
Default constructors don't initialize memory, and while it won't hurt to do it, there's nothing gained by initializing something to a value that you turn around and overwrite right away. As I said before, it's just a safe habit to develop so that you don't forget to do it when you need to.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
nbaztec
She says:
1. Why the hell use int main() when void main() works fine.
It does?
Code:
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !
Your Comeau C/C++ test results are as follows:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 1: error: return type of function "main" must be "int"
So use int main() OR int main(int argc, char *argv[])
void main()
^
1 error detected in the compilation of "ComeauTest.c".
In strict mode, with -tused, Compile failed
Also, technically, it need not work fine.
There are some older compilers out there that will produce code that will fail if the wrong return type for main() is used (unfortunately, these compilers do not check if you have the wrong return type for main). The reason for this is that you, the programmer, is indicating to the compiler one thing (that main doesn't return anything), but in reality, main() does return something. So code is generated that implies that a return is not done, but a return is done.
So what do you have? You have a program that either produces undefined behaviour on exit, or some other issue -- usually return/stack related issues.
The correct return type for main() is int. There is no ambiguity about it.
Here is an older 'C' link:
http://users.aber.ac.uk/auj/voidmain.shtml
Regards,
Paul McKenzie
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by Paul McKenzie
The situation for C is slightly different as C99 permits the main function (in a hosted environment) to have a return type other than int if the implementation allows for it, thus nbaztec's teacher could use this combined with the compiler's documentation as a defense, albeit a poor defense that is rather unbecoming of a teacher. (Why mandate something compiler specific when something standard is available with no disadvantage?) But the class is apparently using C++, so this point is moot as the compiler itself is non-conforming in this respect.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
GCDEF
I just bought a PC with 6GB of RAM for $409. RAM is cheap.
Wish I could have 1 too..
Quote:
Originally Posted by
GCDEF
You want to be careful, but if you're reusing variables rather than allocating a few extra ints, you're not programming well.
I only use variables which I am **** sure wont be used again, as in a case switch nearing program termination. But if a problem can be done without the need of additional 2 bytes, its always better. For small problems this can be rightfully achieved. Though I personally declare separate variables in my day-to-day projects which span thousands of lines, just for the sake of better understandability of various variables.
Quote:
Default constructors don't initialize memory,
Yes, I know, but they do initialize. so maybe i "guess" int
Quote:
As I said before, it's just a safe habit to develop so that you don't forget to do it when you need to.
Quote:
Whenever something can be done in two ways, someone will be confused. Whenever something is a matter of taste, discussions can drag on forever. Stick to one pointer per declaration and always initialize variables and the source of confusion disappears.
-Bjarne Stroustrup's Comment
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
laserlight
The situation for C is slightly different as C99 permits the main function (in a hosted environment) to have a return type other than int if the implementation allows for it, thus nbaztec's teacher could use this combined with the compiler's documentation as a defense, albeit a poor defense that is rather unbecoming of a teacher. (Why mandate something compiler specific when something standard is available with no disadvantage?) But the class is apparently using C++, so this point is moot as the compiler itself is non-conforming in this respect.
Really, does C99(does C89?) really permit other datatypes, I mean, I cant imagine the blasphemy it will bring upon the OS if my Windows/LinuX detects 'A'/2.3657 coming as a return type -_-"
And ya the compiler(TC++ -classic, I personally hate it.) is somewhere b/w C & C++, and at the same time neither both, it reports some errors of C & some of inherited C++.
P.S. void main() is like a manifested pestilence & ignorance is the one breeding it. I laugh when people say void main() is better coz u dont have to return anything. The best part, they dont even know where that return value goes...Will love to see their PCs crashing 1 day, just because of a stack overflow/pop arising outta void main().
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
nbaztec
Wish I could have 1 too..
But if a problem can be done without the need of additional 2 bytes, its always better.
No it's not. Ease of maintenance and readability is way, way, way more important than saving two bytes. Variables should be named to give an indication of what they do and how they're used. If somebody that worked for me named variables a, b and c, they'd be rewriting their code or looking for new work. Code has to be easy to understand.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
laserlight
In the case where a variable will be immediately assigned to, initialisation for the sake of initialisation might confuse a reader - or it might not - thus it becomes a matter of style. But this is only if it is coupled with the rule that variables should be declared near first use, otherwise the initialisation becomes initialisation for the sake of defensive programming.
Agreed it's a Defensive Programming, but so are try, catch, throw. But I know you too might have used various GDI functions for Windows Identifiers, Pids, Process Identifiers....and I many a times got erratic results, just because I didnt ZeroMemory() or NULL them.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by nbaztec
Really, does C99(does C89?) really permit other datatypes
I believe C89 does as well, but I do not feel like checking for something that has little practical use when just using int as the return type will always work on a conforming implementation.
Quote:
Originally Posted by nbaztec
I mean, I cant imagine the blasphemy it will bring upon the OS if my Windows/LinuX detects 'A'/2.3657 coming as a return type -_-"
I guess that it is the implementation's job to translate whatever value you return with the return types that it allows to something that makes sense to the host environment.
Quote:
Originally Posted by GCDEF
No it's not. Ease of maintenance and readability is way, way, way more important than saving two bytes. Variables should be named to give an indication of what they do and how they're used. If somebody that worked for me named variables a, b and c, they'd be rewriting their code or looking for new work. Code has to be easy to understand.
Furthermore, data flow analysis might result in the compiler optimising such that the two byte penalty is only imaginary.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
GCDEF
No it's not. Ease of maintenance and readability is way, way, way more important than saving two bytes. Variables should be named to give an indication of what they do and how they're used. If somebody that worked for me named variables a, b and c, they'd be rewriting their code or looking for new work. Code has to be easy to understand.
uhh...seems you missed my point there... I also added this:
"Though I personally declare separate variables in my day-to-day projects, which span thousands of lines, just for the sake of better understandability of various variables."
I meant in simple programs like Matrix Calculators, Star/Number Pyramids (From MFC to this, I sometimes lol), etc. etc. why declare another variable.
-
Re: Reinitializing variables & their speed sacrifice
I would argue that the ability of a variable to "span thousands of lines" implies that your functions are too long to begin with. Functions should be short, concise bits of functionality which can be tested easily; the shorter the better (within reason).
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
Lindley
I would argue that the ability of a variable to "span thousands of lines" implies that your functions are too long to begin with. Functions should be short, concise bits of functionality which can be tested easily; the shorter the better.
lol! not "variables" the "code" spans thousands of lines utilizing many custom headers....
Making variables spanning thousands of lines would only be possible if I sleep upon my keyboard with my nose constantly pressing "A" then suddenly I turn and bingo a much coveted ';'
lolz... :D
EDIT: Perhaps I shud throw in 1 more comma. Fixing Now.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by Lindley
I would argue that the ability of a variable to "span thousands of lines" implies that your functions are too long to begin with.
I think that "span thousands of lines" applies to the project, not the variable.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
nbaztec
Agreed it's a Defensive Programming, but so are try, catch, throw. But I know you too might have used various GDI functions for Windows Identifiers, Pids, Process Identifiers....and I many a times got erratic results, just because I didnt ZeroMemory() or NULL them.
try and catch are legitimate error handling mechanisms. If you want to call error handling "defensive programming", I'd agree, but all programs ought to handle errors.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
nbaztec
uhh...seems you missed my point there... I also added this:
"Though I personally declare separate variables in my day-to-day projects, which span thousands of lines, just for the sake of better understandability of various variables."
I meant in simple programs like Matrix Calculators, Star/Number Pyramids (From MFC to this, I sometimes lol), etc. etc. why declare another variable.
I was taking issue with your blanket statement "But if a problem can be done without the need of additional 2 bytes, its always better."
I would disagree, strongly at that. Who cares about two bytes when memory is measured in gigabytes these days.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
GCDEF
Who cares about two bytes when memory is measured in gigabytes these days.
Though agree on first statement, but this is rather over-hyped. I once almost gave all of my ram away, just because I wanted to compute upon 999K-digited number(& I mean multiplication), then I realized that if i made that class element of linkd list as short int, much of my memory cud be spared. Though agreed Cheap Memory does have its pros....
-
Re: Reinitializing variables & their speed sacrifice
Well, there's a huge difference between saving 2 bytes and saving 2 bytes in a frequently-used object. Saving 2 bytes total is essentially irrelevant. But if you cut down a class size by 2 bytes, and you use 500000 objects of that class, you've just saved yourself a lot more.
So just play it by ear, and save what you can, if you need to. (If you haven't determined you need to reduce your memory usage, don't worry about doing so more than is trivial to do.)
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
GCDEF
I just bought a PC with 6GB of RAM for $409. RAM is cheap. You want to be careful, but if you're reusing variables rather than allocating a few extra ints, you're not programming well.
Default constructors don't initialize memory, and while it won't hurt to do it, there's nothing gained by initializing something to a value that you turn around and overwrite right away. As I said before, it's just a safe habit to develop so that you don't forget to do it when you need to.
I disagree with the statement that there is nothing to gain from the initialization. In the original example scanf was used to write to the variable. Likewise if cin was used it is possible for the extraction to fail leaving the variable initialized to who knows what. std::cin provides failure detection but I am not sure that scanf does. Depending on what your program subsequently does that kind of logic can lead to unexpected behavior. You are right in the third case where the for loop resets the variable to zero unnecessarily. However in that case the programmer could have just left the first part of the for loop empty. To some degree it could be a matter of preference. I like my functions to initialize everything to a known state so that if something fails I don't end up looking at garbage values within the debugger.
I could understand leaving an array uninitialized if you know you are going to completely overwrite it with data anyway provided that it is unlikely that a failure will occur or there is some performance requirement that requires that you don't zero initialize. Again if the write doesn't work I don't want to see an uninitialized buffer full of garbage while debugging. If you are talking about a buffer that was initialized from a binary file or image of some kind it may not be easy to determine if the pattern within memory is good data or bad but if it were zero initialized you can tell that it is still empty very easily. some people don't like to use std::vector for this reason because they don't want zero initialization to occur during construction of the object. If the initialization causes serious performance degradation then I can understand that. However, if it is rather small and doesn't cause me problems I would prefer to zero initialize anyway.
I understand that some might disagree but I was just offering my point of view.
-
Re: Reinitializing variables & their speed sacrifice
1) Technically speaking... int main(argc, argv**) on Windows, another void * on linux and another int on top of that for Mac. :P
2) You're not using it, don't initialize it. It's good practice for debugging, but not release. Most debuggers will null initialize things to BAADF00D or DEADBEEF anyway.
3) Don't even declare the variable outside of the loop, you can declare it in the loop with C++. Not in C granted, but with C++ it's better because the optimizer can do more with it.
ZeroMemory is not C++, it's Windows API. You should only do that if you want the majority of the structure to be zero. You're right about the effects being minimal, but remember that a lot of us go through millions of recursive functions, and work in data sets in the gigabytes, in those cases it starts to matter.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
kempofighter
std::cin provides failure detection but I am not sure that scanf does.
The scanf() family of functions returns the number of format specifiers corresponding to successful conversions. So it does provide failure detection so long as you include at least one format specifier (other than %n) in the string.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
ninja9578
2) You're not using it, don't initialize it. It's good practice for debugging, but not release. Most debuggers will null initialize things to BAADF00D or DEADBEEF anyway.
Most? Not sure about that. very few that I have used will do that. I remember that visual studio did that for me back when I used it. Sometimes profilers will do that in order to help detect potential problems. I'd rather not rely on the compiler to do that. The compiler does it to help you find situations where you forgot to do it and then you go fix it. Also if you aren't using it don't even create it in the first place.
Quote:
Originally Posted by
ninja9578
ZeroMemory is not C++, it's Windows API. You should only do that if you want the majority of the structure to be zero. You're right about the effects being minimal, but remember that a lot of us go through millions of recursive functions, and work in data sets in the gigabytes, in those cases it starts to matter.
I know that the windows API has some kind of a zeroMem function but I never suggested that anyone use it since it isn't portable. I was suggesting that initial values be suplied to the constructors or that the constructor default initializes all values. I don't even write windows programs so the thought of the zeromem function never even entered my mind.
A lot of who go through millions of recursive functions? I never have. I did specifically state that there are cases like that where you don't want to zero initialize a giant array of data. For buffers that are overwritten multiple times I don't suggest zero initializing multiple times but I still think that if it doesn't degrade performance that it is good to allow zero initialization upon creation.
Anyway, do it however you want in your own program. Opinions will always vary on the subject.
-
Re: Reinitializing variables & their speed sacrifice
Someone may have already stated this, but there is an important difference between initialized & uninitialized data in that uninitialized data ends up in the .bss segment (assuming it's supported on the particular platform), and thus does not add to the executable size (since it will not be stored in the executable). Initialized data will go into the .data segment along with it's initial value, and thus becomes part of the exe. I believe the exception to this is static data which I *think* is always initialized in the .data segment.
In the OP's given example this may not matter, but large programs can be drastically affected in code size depending on whether the data is initialized or not. Try using large int arrays in the given example with and without initialization (and with/without static) and the difference in exe size should be apparent.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
ninja9578
2) You're not using it, don't initialize it. It's good practice for debugging, but not release. Most debuggers will null initialize things to BAADF00D or DEADBEEF anyway.
Agreed on debugging aspect, as we're the only one's operating. But once RTM, nobody knows how the code will behave on diff PCs( a la run-time errors), owing to a Corrupted RAM, 99% CPU usage, Virus, etc. The user may even be an Average Joe, and wouldn't be as accustomed as we to our own developed app. So IMO it's always gud to initialize.
Quote:
3) Don't even declare the variable outside of the loop, you can declare it in the loop with C++. Not in C granted, but with C++ it's better because the optimizer can do more with it.
Ya, I dont. But C doesn't permit this. C++ does n I'm more than familiar with this.
Quote:
ZeroMemory is not C++, it's Windows API. You should only do that if you want the majority of the structure to be zero. You're right about the effects being minimal, but remember that a lot of us go through millions of recursive functions, and work in data sets in the gigabytes, in those cases it starts to matter.
Well as for ZeroMem() I mostly develop Windows Apps, so I apologize for not stating otherwise.
The better compilers, assign 0 to ints 0.0 to floats and NULL for chars automatically. So if we take it for granted that every compiler will be like this, the code has a slight chance to show abnormal behavior on diff compilers.
And since the question has been popped up of recursive functions, personally I hate them, unless they are the CALLBACK functions utilizing Windows Procedures. But in normal C/C++, which is better in terms of Performance:
a) A Loop
b) A Recursive Function
I guess so: A loop, as a function is called again and again (and sometimes....again) thus affecting speed greatly.
-
Re: Reinitializing variables & their speed sacrifice
Trivial recursion should certainly be replaced with a loop. But in divide-and-conquer algorithms where a function contains two or more recursive calls, converting to a loop is usually more trouble than it's worth; you quickly reach the point where you're obfuscating what the function actually does for the sake for a few milliseconds, which of course is bad form.
As always, the rule is: Keep the code obvious until you've profiled and determined that it needs to be faster, and where.
-
Re: Reinitializing variables & their speed sacrifice
Quote:
Originally Posted by
nbaztec
Agreed on debugging aspect, as we're the only one's operating. But once RTM, nobody knows how the code will behave on diff PCs( a la run-time errors), owing to a Corrupted RAM, 99% CPU usage, Virus, etc. The user may even be an Average Joe, and wouldn't be as accustomed as we to our own developed app. So IMO it's always gud to initialize.
That made little to no sense to me. What does corrupted RAM, viruses, cpu utilization and what the average user is accustomed to have to do with initializing variables?
Are you an experienced programmer or a student taking a C++ course?