I have encounter a horrible situation.
I usually use visual code to edit my code, also compile and execute in it(F5).
But I found vscode is too smart or ignore some warning message for me. And
output the right answer, which also work fine in Ideone. But in window cmd or dev C++ my code can't output anything, just return a big number.
And I find some situation will occur the thing I mention above.
The code like this
for (i = 0; i < g.size(); i++)
{
int source;
int dest;
int minWeight = 999;
for (j = 0; i < g[j].size(); j++)
{
// no edge, come to next condition
if (!g[i][j])
continue;
if (g[i][j] < minWeight)
{
source = i;
dest = j;
minWeight = g[i][j];
}
}
if
updateGroup(index, index[source], index[dest]);
else
updateGroup(index, index[source], index[dest]);
}
You may found that the second for loops have wrong condition statement, it should change
j = 0; i < g[j].size(); j++ to j = 0; j < g[i].size(); j++
So I wonder to know
Are there any way let my vscode more strict?
Why it still can output right answer in vscode and ideone?
How to avoid or be easier to found where my code wrong when this kind of no message error?
Really hope someone can help me, and appreciate all of your suggestion!!
There is no way for the compiler or computer to read your mind and guess what you meant to write instead of what you really did mean.
Even when this mistake results in a bug, it cannot know that you did not intend to write this, or that you meant to write some other specific thing instead.
Even when this bug results in your program having undefined behaviour, it is not possible to detect many cases of undefined behaviour, and it is not worthwhile for a compiler author to attempt to write code to do this, because it's too hard and not useful enough. Even if they did, the compiler could still not guess what you meant instead.
Remember, loops like this don't have to check or increment the same variable that you declared in the preamble; that's just a common pattern (now superseded by the safer ranged-for statement). There's nothing inherently wrong with having a loop that increments i but checks j.
Ultimately, the solution to this problem is to write tests for your code, which is why many organisations have dedicated Quality Assurance teams to search for bugs, and why you should already be testing your code before committing it to your project.
Remember to concentrate and pay close attention and read your code, and eventually such typos will become less common in your work. Of course once in a while you will write a bug, and your tests will catch it. Sometimes your tests won't catch it, which is when your customers will eventually notice it and raise a complaint. Then, you release a new version that fixes the bug.
This is all totally normal software development practice. That's what makes it fun! 😊
1) Crank up your compiler warnings as high as they will go.
2) Use multiple different compilers (they all warn about different things).
3) Know the details of the language well (a multi year effort) and be really, really careful about the code you write.
4) Write (and regularly run) lots of tests.
5) Use tools like sanitizers, fuzzers, linters, static code analyzers etc. to help catch bugs.
6) Build and run your code on multiple platforms to keep it portable and find bugs exposed by different environments/implementations.
Let's consider following loop in C++, where A is vector or other container using .size():
for(int n=0; n < A.size(); ++n)
cout << A[n];
I think it is equivalent to the loop below (at least in this case, if it is not really absolutely equivalent, can you help me to figure out why? I cannot find a counter-example to that)
for(int n=-1; ++n < A.size(); )
cout << A[n];
Is using first loop somehow better than second one? I see people using first loop everywhere, but never saw a second one. Why no one do this like in second example? Are there some counter-indication to not do this?
In both cases, value of n is the same when we execute second line of code, also while exiting loop, we have the same value. Can anything go wrong in the second loop?
For me, second one seems even simpler.
The first one is better because it is conventional. The second one will leave future readers scratching their heads and cursing your name.
Starting at minus one and then incrementing by one to get 0 in the conditional is not a great thing.
I doubt very much the code generated will be different (aside from the loading of zero to a register is possibly more optimal than -1, which may need a full 32 bit value, where zero usually has a short form or can be achieved with "subtract register from itself" or "xor register with itself".
Making the code harder to read is no benefit. If the compiler deems that this sort of solution is better for some reason, then let it mess about with the code. It's even possible that you are MISSING some optimisation tricks because you are using an "unusual" pattern.
If you want to remove the third part of the for-loop, may I suggest a more typical approach:
for(int n=0; n < A.size();)
cout << A[n++];
(Note that for 'standard' types such as int, n++ and ++n should be equivalent in any modern compiler)
I have a simple for-loop in C++ and the initialization statement is:
for (int n = 0; n < this->fileLines.size(); n++) {
For some crazy reason, the value of n is being set not to 0 but to 249758, which causes the for-loop to evaluate wrong.
Any ideas why this is initializing wrong (i.e., not to 0)?
I think you need to verify after the for loop what the value of n is, I don't see any way this could non-0. Check the value at the start of the switch. Your breakpoint may have interrupted before n was actually set.
Have you tried sticking
std::cerr<<n<<std::endl;
inside of the for loop? This seems a more direct way of observing the value during the running of the program to verify whether or not it is doing what you think, and optimization will not give you problems with this output.
Perhaps your program is multithreaded and someone is inappropriately writing to that memory location?
Is there anything speaking against a structure like to following. In Release mode, Visual Studio seems to ignore i < 10 and execute the loop without end. If I set a break point I see that i runs from 0 to 9 and stays at 9 in all further iterations. If I printf i, I get a error after the 10 iteration, because arr only has 10 fields. Very strange. Please help.
for (i = 0; i < 10; i++){
switch (arr[i].type1){
case A:
//something
break;
case B:
switch (arr[i].type2){
//something
}
break;
default:
break;
}
}
Thanks!
EDIT: I removed all switch statements and replaced them with if statements. Work perfectly now. I still have difficulty believing that I was right and Visual Studio wrong. What about all my other Switch statements in the program? :/
I suspect that
// something
might have something to do with it. If you run this code as is (with the actual case code removed) -- does it happen?
How about if you take the entire switch and put it in a function?
You might be changing i somewhere in that // something either directly, or by some memory bounds issue.
nothing wrong with your example. Perhaps you have some accidental stack-overwriting or something like that in other parts of your code that introduce weird side effects in that place (and no sense making debugging sessions)?
Change the loop variable to j and make the first line of the loop:
int i = j;
Does it still do it?
As long as I don't know what // something does, I'll just give you the best idea I have given what I know;
If this only occurs in release mode, I would guess that the optimization done by the compiler may be the cause if this odd behaviour.
If you can make this occur reliably with the exact code given above, I'd say you should try turning off optimization and see if that helps.
Disclaimer: I tried to search for similar question, however this returned about every C++ question... Also I would be grateful to anyone that could suggest a better title.
There are two eminent loop structure in C++: while and for.
I purposefully ignore the do ... while construct, it is kind of unparalleled
I know of std::for_each and BOOST_FOREACH, but not every loop is a for each
Now, I may be a bit tight, but it always itches me to correct code like this:
int i = 0;
while ( i < 5)
{
// do stuff
++i; // I'm kind and use prefix notation... though I usually witness postfix
}
And transform it in:
for (int i = 0; i < 5; ++i)
{
// do stuff
}
The advantages of for in this example are multiple, in my opinion:
Locality: the variable i only lives in the scope of the loop
Pack: the loop 'control' is packed, so with only looking at the loop declaration I can figure if it is correctly formed (and will terminate...), assuming of course that the loop variable is not further modified within the body
It may be inlined, though I would not always advised it (that makes for tricky bugs)
I have a tendency therefore not to use while, except perhaps for the while(true) idiom but that's not something I have used in a while (pun intended). Even for complicated conditions I tend to stick to a for construct, though on multiple lines:
// I am also a fan of typedefs
for (const_iterator it = myVector.begin(), end = myVector.end();
it != end && isValid(*it);
++it)
{ /* do stuff */ }
You could do this with a while, of course, but then (1) and (2) would not be verified.
I would like to avoid 'subjective' remarks (of the kind "I like for/while better") and I am definitely interested to references to existing coding guidelines / coding standards.
EDIT:
I tend to really stick to (1) and (2) as far as possible, (1) because locality is recommended >> C++ Coding Standards: Item 18, and (2) because it makes maintenance easier if I don't have to scan a whole body loop to look for possible alterations of the control variable (which I takes for granted using a for when the 3rd expression references the loop variables).
However, as gf showed below, while do have its use:
while (obj.advance()) {}
Note that this is not a rant against while but rather an attempt to find which one of while or for use depending on the case at hand (and for sound reasons, not merely liking).
Not all loops are for iteration:
while(condition) // read e.g.: while condition holds
{
}
is ok, while this feels forced:
for(;condition;)
{
}
You often see this for any input sources.
You might also have implicit iteration:
while(obj.advance())
{
}
Again, it looks forced with for.
Additionally, when forcing for instead of while, people tend to misuse it:
for(A a(0); foo.valid(); b+=x); // a and b don't relate to loop-control
Functionally, they're the same thing, of course. The only reason to differentiate is to impart some meaning to a maintainer or to some human reader/reviewer of the code.
I think the while idiom is useful for communicating to the reader of the code that a non-linear test is controlling the loop, whereas a for idiom generally implies some kind of sequence. My brain also kind of "expects" that for loops are controlled only by the counting expression section of the for statement arguments, and I'm surprised (and disappointed) when I find someone conditionally messing with the index variable inside the execution block.
You could put it in your coding standard that "for" loops should be used only when the full for loop construct is followed: the index must be initialized in the initializer section, the index must be tested in the loop-test section, and the value of the index must only be altered in the counting expression section. Any code that wants to alter the index in the executing block should use a while construct instead. The rationale would be "you can trust a for loop to execute using only the conditions you can see without having to hunt for hidden statements that alter the index, but you can't assume anything is true in a while loop."
I'm sure there are people who would argue and find plenty of counter examples to demonstrate valid uses of for statements that don't fit my model above. That's fine, but consider that your code can be "surprising" to a maintainer who may not have your insight or brilliance. And surprises are best avoided.
i does not automatically increase within a while loop.
while (i < 5) {
// do something with X
if (X) {
i++;
}
}
One of the most beautiful stuff in C++ is the algorithms part of STL. When reading code written properly using STL, the programmer would be reading high-level loops instead of low-level loops.
I don't believe that compilers can optimize significantly better if you chose to express your loop one way or the other. In the end it all boils down to readability, and that's a somewhat subjective matter (even though most people probably agree on most examples' readability factor).
As you have noticed, a for loop is just a more compact way of saying
type counter = 0;
while ( counter != end_value )
{
// do stuff
++counter;
}
While its syntax is flexible enough to allow you to do other things with it, I try to restrict my usage of for to examples that aren't much more complicated than the above. OTOH, I wouldn't use a while loop for the above.
I tend to use for loops when there is some kind of counting going on and the loop ends when the counting ends. Obviously you have your standard for( i=0; i < maxvalue; i++ ), but also things like for( iterator.first(); !iterator.is_done(); iterator.next() ).
I use while loops when it's not clear how many times the loop might iterate, i.e. "loop until some condition that cannot be pre-computed holds (or fails to hold)".
// I am also a fan of typedefs
for (const_iterator it = myVector.begin(), end = myVector.end();
it != end && isValid(*it);
++it)
{ /* do stuff */ }
It seems to me that the above code, is rather less readable than the code below.
// I am also a fan of typedefs
const_iterator it = myVector.begin();
end = myVector.end();
while(it != end && isValid(*it))
{
/* do stuff */
++it}
Personally, I think legibility trumps these kind of formatting standards. If another programmer can't easily read your code, that leads to mistakes at worst, and at best it results in wasted time which costs the company money.
In Ye Olde C, for and while loops were not the same.
The difference was that in for loops, the compiler was free to assign a variable to a CPU register and reclaim the register after the loop. Thus, code like this had non-defined behaviour:
int i;
for (i = 0; i < N; i++) {
if (f(i)) break;
}
printf("%d", i); /* Non-defined behaviour, unexpected results ! */
I'm not 100% sure, but I believe this is described in K&R
This is fine:
int i = 0;
while (i < N) {
if (f(i)) break;
i++;
}
printf("%d", i);
Of course, this is compiler-dependent. Also, with time, compilers stopped making use of that freedom, so if you run the first code in a modern C compiler, you should get the expected results.
I wouldn't be so quick to throw away do-while loops. They are useful if you know your loop body will run at least once. Consider some code which creates one thread per CPU core. With a for loop it might appear:
for (int i = 0; i < number_of_cores; ++i)
start_thread(i);
Uentering the loop, the first thing that is checked is the condition, in case number_of_cores is 0, in which case the loop body should never run. Hang on, though - this is a totally redundant check! The user will always have at least one core, otherwise how is the current code running? The compiler can't eliminate the first redundant comparison, as far as it knows, number_of_cores could be 0. But the programmer knows better. So, eliminating the first comparison:
int i = 0;
do {
start_thread(i++);
} while (i < number_of_cores);
Now every time this loop is hit there is only one comparison instead of two on a one-core machine (with a for loop the condition is true for i = 0, false for i = 1, whereas the do while is false all the time). The first comparison is omitted, so it's faster. With less potential branching, there is less potential for branch mispredicts, so it is faster. Because the while condition is now more predictable (always false on 1-core), the branch predictor can do a better job, which is faster.
Minor nitpick really, but not something to be thrown away - if you know the body will always run at least once, it's premature pessimization to use a for loop.