Avoid stepping out of block in Visual C++ 2008 - c++

Considering this code:
std::vector<myObject*> veryLargeArray;
for (int i = 0; i < veryLargeArray.size(); ++i)
{
param_type* currParams = veryLargeArray[i]->GetParams<param_type>();
currParams->phi = /* some complex formula */;
}
How would I step that code such that I know what answer is being stored in phi before another iteration of the loop starts which will effectively destroy currParams and with it my chances of watching its values in the debugger?
I am running into this situation all too often and my solution is to either recompile the code by putting a dummy variable just before the end of the block where I then put the break OR go through the array of values, which sometimes may be huge, just so that I can see what value was stored or may require extra work just to convert the stored param_type into the correct object. Both solutions are not ideal as the first introduces warnings (which is treated as an error, in which case I have to set per file rules) as well as recompilation of the code, both of which I would like to avoid, while the second wastes time.

You could have a tracepoint output the value of phi on each iteration through the loop. You should even be able to combine this with breakpoint conditions.

Set a break point on closing bracket. Open breakpoints window (Ctrl+D, B) and in the list of breakpoints select your breakpoint. Right click and select "Condition". In the condition dialog enter "i==veryLargeArray.Size()-1". Ok dialog and F5 ;-)

You could declare a variable declared outside of the loop to store your value between iterations and set a breakpoint on the closing bracket.
std::vector<myObject*> veryLargeArray;
int inspector; // assuming currParams->phi is int, change type accordingly
for (int i = 0; i < veryLargeArray.size(); ++i)
{
param_type* currParams = veryLargeArray[i]->GetParams<param_type>();
currParams->phi = /* some complex formula */;
inspector = currParams->phi;
}

Related

Should I refer std::vector size when the number is explicitly given

I'm coding a simple function using std::vector below where input is an integer vector and the function proceeds the iteration based on the number of elements in the vector.
In terms of space and time efficiency, which following code are suitable?
HugeClass is actually a Big Integer which contains complex arithmetic while I put a simple arithmetic below for simplicity.
1) Gives a dimension of vector
void (HugeClass& huge, std::vector<int>& vec, int dim){
for(int i=0;i<dim;i++){
huge+=vec[i];
}
}
2) Calls a std::vector.size() to iterate
void (HugeClass& huge, std::vector<int>& vec){
for(int i=0;i<vec.size();i++){
huge+=vec[i];
}
}
dim can range in [100,1000000]
The syntax of a for loop in C++ is:
for ( init; condition; increment ) {
statement(s);
}
Here is the flow of control in a for loop:
The init step is executed first, and only once. This step allows you to declare and initialize any loop control variables. You are not required to put a statement here, as long as a semicolon appears.
Next, the condition is evaluated. If it is true, the body of the loop is executed. If it is false, the body of the loop does not execute and flow of control jumps to the next statement just after the for loop.
After the body of the for loop executes, the flow of control jumps back up to the increment statement. This statement allows you to update any loop control variables. This statement can be left blank, as long as a semicolon appears after the condition.
So in the case of
for(int i=0;i<vec.size();i++) {
huge+=vec[i];
}
vec.size() called each time but is probably inlined, and is probably a simple function.
On top of which
A smart enough optimizer may be able to deduce that it is a loop invariant with no side effects and elide it entirely (this is easier if the code is inlined, but may be possible even if it is not if the compiler does global optimization)

How to exit a single turn of a `for` loop?

In a loop like so,
for (int i = 0; i < 5; i++)
{
int i_foo;
i_foo = foo();
if (i < 5)
return; //<-------- Right here
footwo();
}
How would I return that one particular turn of the loop?
I know that I could make footwo() execute under the condition that i >= 5, but I'm wondering if there is a way to make the loop exit (just the once).
For more explanation, I would like the for loop to start back at the beginning and add 1 to i, as if it had just finished that particular "loop" of the loop.
(I could not find an answer to this based on the strange wording, but if there is one just direct me and I will happily take this down.)
Use continue:
if (i < 5)
continue;
This jumps straight to the next iteration of the loop.
I'm not entirely sure what you mean but if you're checking the condition of if (i < 5) then just use the keyword continue. If the expression is true the loop will continue.
I'm not exactly what you're saying, but to clear up a bit of terminology, I think you mean to say "iteration" when you're saying a "turn of the loop" or a "loop of the loop." Common terms allow for better clarity.
As to your issue:
If you use the continue keyword, it allows you to skip to the next iteration. If you use the break keyword, it will skip past the entire iteration structure (out of the for loop entirely). This also works with while statements.
You can use continue to terminate the current iteration of a loop without terminating the loop itself. But depending on how your code is structured, an if statement might be cleaner.
Given your example, you might want:
for (int i = 0; i < 5; i++)
{
int i_foo;
i_foo = foo();
if (i_foo >= 5) {
footwo();
}
}
I'm assuming that you meant to assign the result of foo() to i_foo, not to i.
A continue can be simpler if you need to bail out from the middle of some nested structure, or if you need to bail out very early in the body of the loop and there's a lot of code that would be shoved into the if.
But in the case of nested control structures, you need to remember that continue applies only to the innermost enclosing loop; there's no construct (other than goto) for bailing out of multiple nested loops. And break applies to the innermost enclosing loop or switch statement.

why is this for loop taking so long?

the for loop:
//for testing, this is usually a value of about 27
int test = level.PathLookupVectors()[globalNodePositionIndex][globalNodeChoice].size();
for (int i = 0; i < level.PathLookupVectors()[globalNodePositionIndex][globalNodeChoice].size(); i++)
{
//adds the correct nodes to the search
search.push_back(level.Nodes()[level.PathLookupVectors()[globalNodePositionIndex][globalNodeChoice][i]].Index());
}
and it's a 64 bit system.
I'm getting very strange results for the integer 'i' when debugging. it should be initialized to 0 but for some reason it's a very very high number which in turn means that the for loop is not executing.
EDIT - just changed it so that it's just an int, now it gets a value
of -82938723047 or some such number. why on earth is this happening?
It's ruining my program!
You are almost certainly barking up the wrong tree. The code:
for (int i = 0;
...initializes i to 0, period. If you're trying to spy its value in the debugger and the debugger says i has a value that looks like uninitialized, garbage data, then you are probably looking at i either before or after i has entered scope and been initialized. For example, in MSVC if you examine i before you enter the loop for the very first time, it will often have garbage data.
These are not the droids you're looking for. Move along.
Much more likely is this code:
level.PathLookupVectors()[globalNodePositionIndex][globalNodeChoice].size()
This is probably not doing what you think it's doing.
By the way, if the type of level.PathLookupVectors()[globalNodePositionIndex][globalNodeChoice] is a vector of some kind, I'd prefer that you use a for loop constructed like this.
/*psudocode*/ for( vector::iterator it = v.begin(), it_end = v.end(); it != it_end; ++it )
If you don't need the index of the element you're trying to access, then why refer to it? You're just introducing another potential failure point in your code.

When to use the for loop over the while loop?

We can use for loop and while loop for same purpose.
in what means they effect our code if I use for instead of while? same question arises between if-else and switch-case? how to decide what to use?
for example which one you would prefer?
This code:
int main()
{
int n = 10;
for(int i=0;i<n;i++)
{
do_something();
}
return 0;
}
Or this code:
int main()
{
int n=10,i=0;
while(i<n)
{
do_something();
i++;
}
return 0;
}
if using for or while loop does not effect the code by any means then may I know What was the need to make 2 solution for same problem?
Use whichever one makes the intention of your code clearest.
If you know the number of iterations the loop should run beforehand, I would recommend the for construct. While loops are good for when the loop's terminating condition happens at some yet-to-be determined time.
I try to prefer the for loop. Why? Because when I see a for loop, I can expect all of the loop bookeeping is kept in a single statement. I can insert break or continue statements without worrying about breaking how the loop operates. And most importantly, the body of the loop focuses on what you actually want the loop to be doing, rather than maintaining the loop itself. If I see a while, then I have to look at and understand the entire loop body before I can understand what iteration pattern the loop uses.
The only place I end up using while is for those few cases where the control of the loop is provided by some outside routine (i.e. FindFirstFileW)
It's all a matter of personal opinion though. Lots of people don't like what I end up doing with for loops because the loop statement often ends up spanning multiple lines.
There are some very subtle differences..
scope of loop variable(s), for example, with the for loop i has local scope, with a while this has to be defined before (which means it is available after, of course you can do that with for as well..)
continue, with a for loop, variable will be increment/decremented, with a while, you'd have to insert the operation before continue
Frankly, if you need to increment/decrement, a for loop makes sense, if you don't know the bounds, and there is no real increment/decrement, a while loop makes more sense, e.g.
while(some_stream >> input)
{
// do stuff...
}
In general, a for loop might be preferable for simple loops, since the logic of the loop is contained in a single line:
for (int i = 0; i < 10; ++i) {...}
However, sometimes we need more complex logic or flow control. A while loop allows us to implement more complicated loops. For example, suppose we only want to increment the counter variable under certain conditions:
int i = 0;
while (i < 10)
{
if (some_condition) ++i;
else if (some_other_condition) { ... }
else break;
}
Just use the one that makes the code readable and logical.
In some cases the compiler (gcc at least) will be able to optimize a very slightly better than a for loop doing the same thing. If I remember correctly that optimization is only about few clock cycles so it probably never will have any noticeable affect on the performance.
You cannot write while(int i=0, i < n); that is, you've to define i before the while loop; means i exists inside as well as outside the loop.
However, in case of for loop, you can define i right in the for loop itself; and so i doesn't exist outside the loop. That is one difference. Just because of this difference, I like for more than while. And use while rarely, when for makes thing more cumbersome!
By no means they affect your program the way it works ! Its the matter of ease to understand better.
switch(i) // Once finding your case, you can easily know where the switch ends
// and thus the next statement of execution
{
case 1: break ;
case 2: break ;
// .....
case 10: break ;
default:break ;
}
if( i==1 ) // Here you have the pain of finding where the last else if ends !
{}
else if( i==2)
{}
// ...
else if( i==10)
{}
However, it is a matter of taste. I prefer switch.

C structure pointer dereferencing speed

I have a question regarding the speed of pointer dereferencing. I have a structure like so:
typedef struct _TD_RECT TD_RECT;
struct _TD_RECT {
double left;
double top;
double right;
double bottom;
};
My question is, which of these would be faster and why?
CASE 1:
TD_RECT *pRect;
...
for(i = 0; i < m; i++)
{
if(p[i].x < pRect->left) ...
if(p[i].x > pRect->right) ...
if(p[i].y < pRect->top) ...
if(p[i].y > pRect->bottom) ...
}
CASE 2:
TD_RECT *pRect;
double left = pRect->left;
double top = pRect->top;
double right = pRect->right;
double bottom = pRect->bottom;
...
for(i = 0; i < m; i++)
{
if(p[i].x < left) ...
if(p[i].x > right) ...
if(p[i].y < top) ...
if(p[i].y > bottom) ...
}
So in case 1, the loop is directly dereferencing the pRect pointer to obtain the comparison values. In case 2, new values were made on the function's local space (on the stack) and the values were copied from the pRect to the local variables. Through a loop there will be many comparisons.
In my mind, they would be equally slow, because the local variable is also a memory reference on the stack, but I'm not sure...
Also, would it be better to keep referencing p[] by index, or increment p by one element and dereference it directly without an index.
Any ideas? Thanks :)
You'll probably find it won't make a difference with modern compilers. Most of them would probably perform common subexpresion elimination of the expressions that don't change within the loop. It's not wise to assume that there's a simple one-to-one mapping between your C statements and assembly code. I've seen gcc pump out code that would put my assembler skills to shame.
But this is neither a C nor C++ question since the ISO standard doesn't mandate how it's done. The best way to check for sure is to generate the assembler code with something like gcc -S and examine the two cases in detail.
You'll also get more return on your investment if you steer away from this sort of micro-optimisation and concentrate more on the macro level, such as algorithm selection and such.
And, as with all optimisation questions, measure, don't guess! There are too many variables which can affect it, so you should be benchmarking different approaches in the target environment, and with realistic data.
It is not likely to be a hugely performance critical difference. You could profile doing each option multiple times and see. Ensure you have your compiler optimisations set in the test.
With regards to storing the doubles, you might get some performance hit by using const. How big is your array?
With regards to using pointer arithmetic, this can be faster, yes.
You can instantly optimise if you know left < right in your rect (surely it must be). If x < left it can't also be > right so you can put in an "else".
Your big optimisation, if there is one, would come from not having to loop through all the items in your array and not have to perform 4 checks on all of them.
For example, if you indexed or sorted your array on x and y, you would be able, using binary search, to find all values that have x < left and loop through just those.
I think the second case is likely to be faster because you are not dereferencing the pointer to pRect on every loop iteration.
Practically, a compiler doing optimisation may notice this and there might be no difference in the code that is generated, but the possibility of pRect being an alias of an item in p[] could prevent this.
An optimizing compiler will see that the structure accesses are loop invariant and so do a Loop-invariant code motion, making your two cases look the same.
I will be surprised if even a totally non-optimized compile (- O0) will produce differentcode for the two cases presented. In order to perform any operation on a modern processor, the data need to loaded into registers. So even when you declare automatic variables, these variables will not exist in main memory but rather in one of the processors floating point registers. This will be true even when you do not declare the variables yourself and therefore I expect no difference in generated machine code even for when you declare the temporary variables in your C++ code.
But as others have said, compile the code into assembler and see for yourself.