How to avoid use of goto and break nested loops efficiently - c++

I'd say that it's a fact that using goto is considered a bad practice when it comes to programming in C/C++.
However, given the following code
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; j++)
{
for (k = 0; k < N; ++k)
{
...
if (condition)
goto out;
...
}
}
}
out:
...
I wonder how to achieve the same behavior efficiently not using goto. What i mean is that we could do something like checking condition at the end of every loop, for example, but AFAIK goto will generate just one assembly instruction which will be a jmp. So this is the most efficient way of doing this I can think of.
Is there any other that is considered a good practice? Am I wrong when I say it is considered a bad practice to use goto? If I am, would this be one of those cases where it's good to use it?
Thank you

The (imo) best non-goto version would look something like this:
void calculateStuff()
{
// Please use better names than this.
doSomeStuff();
doLoopyStuff();
doMoreStuff();
}
void doLoopyStuff()
{
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; j++)
{
for (k = 0; k < N; ++k)
{
/* do something */
if (/*condition*/)
return; // Intuitive control flow without goto
/* do something */
}
}
}
}
Splitting this up is also probably a good idea because it helps you keep your functions short, your code readable (if you name the functions better than I did) and dependencies low.

If you have deeply-nested loops like that and you must break out, I believe that goto is the best solution. Some languages (not C) have a break(N) statement that will break out of more than one loop. The reason C doesn't have it is that it's even worse than a goto: you have to count the nested loops to figure out what it does, and it's vulnerable to someone coming along later and adding or removing a level of nesting, without noticing that the break count needs to be adjusted.
Yes, gotos are generally frowned upon. Using a goto here is not a good solution; it's merely the least of several evils.
In most cases, the reason you have to break out of a deeply-nested loop is because you're searching for something, and you've found it. In that case (and as several other comments and answers have suggested), I prefer to move the nested loop to its own function. In that case, a return out of the inner loop accomplishes your task very cleanly.
(There are those who say that functions must always return at the end, not from the middle. Those people would say that the easy break-it-out-to-a-function solution is therefore invalid, and they'd force the use of the same awkward break-out-of-the-inner-loop technique(s) even when the search was split off to its own function. Personally, I believe those people are wrong, but your mileage may vary.)
If you insist on not using a goto, and if you insist on not using a separate function with an early return, then yes, you can do something like maintaining extra Boolean control variables and testing them redundantly in the control condition of each nested loop, but that's just a nuisance and a mess. (It's one of the greater evils that I was saying using a simple goto is lesser than.)

I think that goto is a perfectely sane thing to do here, and is one of it's exceptional use cases per the C++ Core Guidelines.
However, perhaps another solution to be considered is an IIFE lambda. In my opinion this is slightly more elegant than declaring a separate function!
[&] {
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; j++)
for (int k = 0; k < N; ++k)
if (condition)
return;
}();
Thanks to JohnMcPineapple on reddit for this suggestion!

In this case you don't wan't to avoid using goto.
In general the use of goto should be avoided, however there are exceptions to this rule, and your case is a good example of one of them.
Let's look at the alternatives:
for (i = 0; i < N; ++i) {
for (j = 0; j < N; j++) {
for (k = 0; k < N; ++k) {
...
if (condition)
break;
...
}
if (condition)
break;
}
if (condition)
break;
}
Or:
int flag = 0
for (i = 0; (i < N) && !flag; ++i) {
for (j = 0; (j < N) && !flag; j++) {
for (k = 0; (k < N) && !flag; ++k) {
...
if (condition) {
flag = 1
break;
...
}
}
}
Neither of these is as concise or as readable as the goto version.
Using a goto is considered acceptable in cases where you're only jumping ahead (not backward) and doing so makes your code more readable and understandable.
If on the other hand you use goto to jump in both directions, or to jump into a scope which could potentially bypass variable initialization, that would be bad.
Here's a bad example of goto:
int x;
scanf("%d", &x);
if (x==4) goto bad_jump;
{
int y=9;
// jumping here skips the initialization of y
bad_jump:
printf("y=%d\n", y);
}
A C++ compiler will throw an error here because the goto jumps over the initialization of y. C compilers however will compile this, and the above code will invoke undefined behavior when attempting to print y which will be uninitialized if the goto occurs.
Another example of proper use of goto is in error handling:
void f()
{
char *p1 = malloc(10);
if (!p1) {
goto end1;
}
char *p2 = malloc(10);
if (!p2) {
goto end2;
}
char *p3 = malloc(10);
if (!p3) {
goto end3;
}
// do something with p1, p2, and p3
end3:
free(p3);
end2:
free(p2);
end1:
free(p1);
}
This performs all of the cleanup at the end of the function. Compare this to the alternative:
void f()
{
char *p1 = malloc(10);
if (!p1) {
return;
}
char *p2 = malloc(10);
if (!p2) {
free(p1);
return;
}
char *p3 = malloc(10);
if (!p3) {
free(p2);
free(p1);
return;
}
// do something with p1, p2, and p3
free(p3);
free(p2);
free(p1);
}
Where the cleanup is done in multiple places. If you later add more resources that need to be cleaned up, you have to remember to add the cleanup in all of these places plus the cleanup of any resources that were obtained earlier.
The above example is more relevant to C than C++ since in the latter case you can use classes with proper destructors and smart pointers to avoid manual cleanup.

Lambdas let you create local scopes:
[&]{
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; j++)
{
for (k = 0; k < N; ++k)
{
...
if (condition)
return;
...
}
}
}
}();
if you also want the ability to return out of that scope:
if (auto r = [&]()->boost::optional<RetType>{
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; j++)
{
for (k = 0; k < N; ++k)
{
...
if (condition)
return {};
...
}
}
}
}()) {
return *r;
}
where returning {} or boost::nullopt is a "break", and returning a value returns a value from the enclosing scope.
Another approach is:
for( auto idx : cube( {0,N}, {0,N}, {0,N} ) {
auto i = std::get<0>(idx);
auto j = std::get<1>(idx);
auto k = std::get<2>(idx);
}
where we generate an iterable over all 3 dimensions and make it a 1 deep nested loop. Now break works fine. You do have to write cube.
In c++17 this becomes
for( auto[i,j,k] : cube( {0,N}, {0,N}, {0,N} ) ) {
}
which is nice.
Now, in an application where you are supposed to be responsive, looping over a large 3 dimensional range at primiary control flow level is often a bad idea. You can thread it off, but even then you end up with problem that the thread runs too-long. And most 3 dimensional large iterations I've played with can benefit from using sub-task threading themselves.
To that end, you'll end up wanting to categorize your operation based on what kind of data it accesses, then pass your operation to something that schedules the iteration for you.
auto work = do_per_voxel( volume,
[&]( auto&& voxel ) {
// do work on the voxel
if (condition)
return Worker::abort;
else
return Worker::success;
}
);
then the control flow involved goes into the do_per_voxel function.
do_per_voxel isn't going to be a simple naked loop, but rather a system to rewrite the per-voxel tasks into per-scanline tasks (or even per-plane tasks depending on how large the planes/scanlines are at runtime (!)) then dispatch them in turn to a thread pool managed task scheduler, stitch up the resulting task handles, and return a future-like work that can be awaited on or used as a continuation trigger for when the work is done.
And sometimes you just use goto. Or you manually break out functions for subloops. Or you use flags to break out of deep recursion. Or you put the entire 3 layer loop in its own function. Or you compose the looping operators using a monad library. Or you can throw an exception (!) and catch it.
The answer to almost every question in c++ is "it depends". The scope of problem and the number of techniques you have available is large, and the details of the problem change the details of the solution.

Alternative - 1
You can do something like follows:
Set a bool variable in the beginning isOkay = true
All of your forloop conditions, add an extra condition isOkay == true
When your your custom condition is satisfied/ fails, set isOkay = false.
This will make your loops stop. An extra bool variable would be sometimes handy though.
bool isOkay = true;
for (int i = 0; isOkay && i < N; ++i)
{
for (int j = 0; isOkay && j < N; j++)
{
for (int k = 0; isOkay && k < N; ++k)
{
// some code
if (/*your condition*/)
isOkay = false;
}
}
}
Alternative - 2
Secondly. if the above loop iterations are in a function, best choice is to return result, when ever the custom condition is satisfied.
bool loop_fun(/* pass the array and other arguments */)
{
for (int i = 0; i < N ; ++i)
{
for (int j = 0; j < N ; j++)
{
for (int k = 0; k < N ; ++k)
{
// some code
if (/* your condition*/)
return false;
}
}
}
return true;
}

Break your for loops out into functions.
It makes things significantly easier to understand because now you can see what each loop is actually doing.
bool doHerpDerp() {
for (i = 0; i < N; ++i)
{
if (!doDerp())
return false;
}
return true;
}
bool doDerp() {
for (int i=0; i<X; ++i) {
if (!doHerp())
return false;
}
return true;
}
bool doHerp() {
if (shouldSkip)
return false;
return true;
}

Is there any other that is considered a good practice? Am I wrong when
I say it is considered a bad practice to use goto?
goto can be misused and overused, but I dont see any of the two in your example. Breaking out of a deeply nested loop is most clearly expressed by a simple goto label_out_of_the_loop;.
It is bad practice to use many gotos that jump to different labels, but in such cases it isnt the keyword goto itself that makes your code bad. It is the fact that you are jumping around in the code making it hard to follow that makes it bad. If however, you need a single jump out of nested loops then why not use the tool that was made for exactly that purpose.
To use a made up out of thin air analogy: Imagine you live in a world where in the past it was hip to hammer nails into walls. In recent times it became more fashinable to drill screws into walls using screwdrivers and hammers are completely out of fashion. Now consider you have to (despite being a bit old-fashinoned) get a nail into a wall. You should not refrain from using a hammer to do that, but maybe you should rather ask yourself if you really need a nail in the wall instead of a screw.
(Just in case it isnt clear: The hammer is goto and the nail in the wall is a jump out of a nested loop while the screw in the wall would be using functions to avoid the deep nesting alltogether ;)

One possible way is to assign a boolean value to a variable that represents the state. This state can later be tested using an "IF" conditional statement for other purposes later on in the code.

as far as your comment on efficiency compiling the both options in release mode on visual studio 2017 produces the exact same assembly.
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
for (int k = 0; k < 5; ++k)
{
if (i == 1 && j == 2 && k == 3) {
goto end;
}
}
}
}
end:;
and with a flag.
bool done = false;
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
for (int k = 0; k < 5; ++k)
{
if (i == 1 && j == 2 && k == 3) {
done = true;
break;
}
}
if (done) break;
}
if (done) break;
}
both produce..
xor edx,edx
xor ecx,ecx
xor eax,eax
cmp edx,1
jne main+15h (0C11015h)
cmp ecx,2
jne main+15h (0C11015h)
cmp eax,3
je main+27h (0C11027h)
inc eax
cmp eax,5
jl main+6h (0C11006h)
inc ecx
cmp ecx,5
jl main+4h (0C11004h)
inc edx
cmp edx,5
jl main+2h (0C11002h)
so there is no gain. Another option if your using a modern c++ compiler is to wrap it in a lambda.
[](){
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
for (int k = 0; k < 5; ++k)
{
if (i == 1 && j == 2 && k == 3) {
return;
}
}
}
}
}();
again this produces the exact same assembly. Personally I think using goto in your example is perfectly acceptable. It is clear what is happening to anyone else, and makes for more concise code. Arguably the lambda is equally as concise.

Specific
IMO, in this specific example, I think it is important to notice a common functionality between your loops. (Now I know that your example isn't necessarily literal here, but just bear with me for a sec) as each loop iterates N times, you can restructure your code like the following:
Example
int max_iterations = N * N * N;
for (int i = 0; i < max_iterations; i++)
{
/* do stuff, like the following for example */
*(some_ptr + i) = 0; // as opposed to *(some_3D_ptr + i*X + j*Y + Z) = 0;
// some_arr[i] = 0; // as oppose to some_3D_arr[i][j][k] = 0;
}
Now, it is important to remember that all loops, while for or otherwise, are really just syntatic sugar for the if-goto paradigm. I agree with the others that you ought to have a function return the result, however I wanted to show an example like the above in which that may not be the case. Granted, I'd flag the above in a code review but if you replaced the above with a goto I'd consider that a step in the wrong direction. (NOTE -- Make sure that you can reliably fit it into your desired datatype)
General
Now, as a general answer, the exit conditions for your loop may not be the same everytime (like the post in question). As a general rule, pull as many unneeded operations out of your loops (multiplications, etc.) as far out as you can as, while compilers are getting smarter everyday, there is no replacement for writing efficient and readable code.
Example
/* matrix_length: int of m*n (row-major order) */
int num_squared = num * num;
for (int i = 0; i < matrix_length; i++)
{
some_matrix[i] *= num_squared; // some_matrix is a pointer to an array of ints of size matrix_length
}
rather than writing *= num * num, we no longer have to rely on the compiler to optimize this out for us (though any good compiler should). So any doubly or triply nested loops which perform the above functionality would also benefit not only your code, but IMO writing clean and efficient code on your part. In the first example, we could have instead had *(some_3D_ptr + i*X + j*Y + Z) = 0;! Do we trust the compiler to optimize out i*X and j*Y, so that they aren't computed every iteration?
bool check_threshold(int *some_matrix, int max_value)
{
for (int i = 0; i < rows; i++)
{
int i_row = i*cols; // no longer computed inside j loop unnecessarily.
for (int j = 0; j < cols; j++)
{
if (some_matrix[i_row + j] > max_value) return true;
}
}
return false;
}
Yuck! Why aren't we using classes provided by the STL or a library like Boost? (we must be doing some low level/high performant code here). I couldn't even write a 3D version, due to the complexity. Even though we have hand optimized something, it may even be better to use #pragma unroll or similar preprocessor hints if your compiler allows.
Conclusion
Generally, the higher the abstraction level you can use, the better, however if say aliasing a 1-Dimensional row-major order matrix of integers to a 2-Dimensional array makes your code-flow harder to understand/extend, is it worth it? Likewise, that also may be an indicator to make something into its own function. I hope that, given these examples, you can see that different paradigms are called for in different places, and its your job as the programmer to figure that out. Don't go crazy with the above, but make sure you know what they mean, how to use them, and when they are called for, and most importantly, make sure the other people using your codebase know what they are as well and have no qualms about it. Good luck!

bool meetCondition = false;
for (i = 0; i < N && !meetCondition; ++i)
{
for (j = 0; j < N && !meetCondition; j++)
{
for (k = 0; k < N && !meetCondition; ++k)
{
...
if (condition)
meetCondition = true;
...
}
}
}

There are already several excellent answers that tell you how you can refactor your code, so I won’t repeat them. There isn’t a need to code that way for efficiency any more; the question is whether it’s inelegant. (Okay, one refinement I’ll suggest: if your helper functions are only ever intended to be used inside the body of that one function, you might help the optimizer out by declaring them static, so it knows for certain that the function does not have external linkage and will never be called from any other module, and the hint inline can’t hurt. However, previous answers say that, when you use a lambda, modern compilers don’t need any such hints.)
I’m going to challenge the framing of the question a bit. You’re correct that most programmers have a taboo against using goto. This has, in my opinion, lost sight of the original purpose. When Edsger Dijkstra wrote, “Go To Statement Considered Harmful,” there was a specific reason he thought so: the “unbridled” use of go to makes it too hard to reason formally about the current program state, and what conditions must currently be true, compared to control flow from recursive function calls (which he preferred) or iterative loops (which he accepted). He concluded:
The go to statement as it stands is just too primitive; it is too much an invitation to make a mess of one's program. One can regard and appreciate the clauses considered as bridling its use. I do not claim that the clauses mentioned are exhaustive in the sense that they will satisfy all needs, but whatever clauses are suggested (e.g. abortion clauses) they should satisfy the requirement that a programmer independent coordinate system can be maintained to describe the process in a helpful and manageable way.
Many C-like programming languages, for example Rust and Java, do have an additional “clause considered as bridling its use,” the break to a label. An even more restricted syntax might be something like break 2 continue; to break out of two levels of the nested loop and resume at the top of the loop containing them. This presents no more of a problem than a C-style break to what Dijkstra wanted to do: defining a concise description of the program state that programmers can keep track of in their heads or a static analyzer would find tractable.
Restricting goto to constructions like this makes it simply a renamed break to a label. The remaining problem with it is that the compiler and the programmer don’t necessarily know you’re only going to use it this way.
If there’s an important post-condition that holds after the loop, and your concern with goto is the same as Dijkstra’s, you might consider stating it in a short comment, something like // We have done foo to every element, or encountered condition and stopped. That would alleviate the problem for humans, and a static analyzer should do fine.

The best solution is to put the loops in a function and then return from that function.
This is essentially the same thing as your goto example, but with the massive benefit that you avoid having yet another goto debate.
Simplified pseudo code:
bool function (void)
{
bool result = something;
for (i = 0; i < N; ++i)
for (j = 0; j < N; j++)
for (k = 0; k < N; ++k)
if (condition)
return something_else;
...
return result;
}
Another benefit here is that you can upgrade from bool to an enum if you come across more than 2 scenarios. You can't really do that with goto in a readable way. The moment you start to use multiple gotos and multiple labels, is the moment you embrace spaghetti coding. Yes, even if you just branch downwards - it will not be pretty to read and maintain.
Notably, if you have 3 nested for loops, that may be an indication that you should try to split your code up in several functions and then this whole discussion might not even be relevant.

Related

Is there only one way to implement a bubble sort algorithm?

I was trying to implement my own bubble sort algorithm without looking at any pseudo-code online, but now that I've successfully done it, mine code looks really different from the examples I see online. They all involve dealing with a swapped variable that is either true or false. My implementation does not include that at all, so did I NOT make a bubble sort?
Here is an example I see online:
for i = 1:n,
swapped = false
for j = n:i+1,
if a[j] < a[j-1],
swap a[j,j-1]
swapped = true
→ invariant: a[1..i] in final position
break if not swapped
end
Here is my implementation of it:
void BubbleSort(int* a, int size)
{
while (!arraySorted(a, size))
{
int i = 0;
while (i < (size-1))
{
if (a[i] < a[i+1])
{
i++;
}
else
{
int tmp = 0;
tmp = a[i+1];
a[i+1] = a[i];
a[i] = tmp;
i++;
}
}
}
}
It does the same job, but does it do it any differently?
As some people noted, your version without the flag works, but is needlessly slow.
However, if you take the original version and just throw away the flag (together with the break), it will still work. It's easy to see from the invariant that you conveniently posted.
The version without the break has roughly the same worst-case performance as with the break (worst case is for an array sorted in reverse order). It's better than the original one if you want an algorithm that is guaranteed to finish in a pre-defined time.
Wikipedia describes another idea for optimization of the bubble-sort, which includes throwing away the break.

Idiom for doing something twice in C++

Is there a common idiom for doing something twice, as in the following situation?
for ( int i = 0; i < num_pairs; i++ ) {
cards.push_back( Card(i) );
cards.push_back( Card(i) );
}
I have a feeling that there's a clearer way than introducing a new loop variable counting from 0 to 1, especially since it isn't used except for counting.
for ( int i = 0; i < num_pairs; i++ )
for ( int j = 0; j < 2; j++ )
cards.push_back( Card(i) );
(Card is just some class I made up and not relevant to the question.)
You probably want to use the fill_n function in <algorithm>
for ( int i = 0; i < num_pairs; i++ )
std::fill_n(std::back_inserter(cards), 2, Card(i));
Personally I would just leave it how it is. It looks clean, it's easy to understand, and it's quite readable. Just leave a comment mentioning why you do it twice (but you would do that no matter what).
I've got a few suggestions. See the last for my recommendation:
In my opinion insert(it, N, value) beats std::fill_n:
for ( int i = 0; i < num_pairs; i++ ) {
cards.insert(cards.end(), 2, Card(i) );
}
If order isn't important, you could just generate the cards once, and duplicate after the fact
std::copy(cards.begin(), cards.end(), std::back_inserter(cards));
Using a dirty lambda and integer division trick. Warning this has the hallmark of a premature optimization: reduces readability for no good reason.
std::vector<Card> cards(num_pairs * 2);
int i = 0;
std::generate_n(cards.begin(), num_pairs, [&i] () { return Card(i++/2); });
(assumes Card is default-constructible. If not, use cards.back_inserter())
My recommendation
The following wins in both performance and expression of intent:
std::vector<Card> cards;
cards.reserve(num_pairs*2);
for (int i = 0; i < num_pairs; ++i)
{
cards.emplace_back(i);
cards.emplace_back(i);
}
You are right about using expanding the inner loop into statements as using another loop only 2 iterations is going to be bad for performance. Due of the frequent jumps, the second one (nested loops) is going to perform slowly. Whether there will be any noticeable difference completely depends on the num_pairs.
So the first one is better for performance(however marginal the gain might be). This sort of expanding loops is called loop unwinding/unrolling in compiler's terminology. However, this term is not used at programming level as usually only compiler does that to make the code faster. Idioms are certain design notions that help programmers write better & efficient code and understand the language better.
If you want to do this very often, write a little utility function:
template<class F>
void repeat(unsigned times, F callback) {
while (times--) callback();
}
// ...
for (int i = 0; i < num_pairs; i++) {
repeat(2, [&] { cards.push_back(Card(i)); });
}
I wrote an example on Ideone.
Your first approach might be confusing to future readers of your code. They might think that the code was there twice by accident. Using a function like this avoids this confusing.
The performance hit would be very minimal, if even > 0, since the compiler is likely to inline the function and completely optimize out the loop for small times'. If you're worried about performance, benchmark first.

Simple loop, which one I would get more performance and which one is recommended? defining a variable inside a loop or outside of it?

Variable outside of the loop
int number = 0;
for(int i = 0; i < 10000; i++){
number = 3 * i;
printf("%d",number);
}
or Variable inside of the loop
for(int i = 0; i < 10000; i++){
int number = 3 * i;
printf("%d",number);
}
Which one is recommended and which one is better in performance?
Edit:
This is just an example to exhibit what I mean, All I wanna know is if defining a variable inside a loop and outside a loop means the same thing , or there's a difference.
Time to learn something early: any optimization you could make on something like this will be irrelevant in the face of printf.
Printf will be very, very slow. You could quintuple the math and get no measurable speed decrease. It's just the nature of printing to the terminal.
As for your edited question, there is no difference defining it in the loop or out. Imagine that
for (i = 0; i < 500; i++) {
int a = i * 3;
}
is just the same as
int forloop::a; // This doesn't work, the idea is to show it just changes the scope
for (i = 0; i < 500; i++) {
a = i * 3;
}
They will produce identical code, unless you start needing to use that variable outside of the loop it is defined in, because it is defined in the local scope of the loop. So...more like this:
int forloop::a; // Still not valid code, just trying to show an explanation
namespace forloop {
for (i = 0; i < 500; i++) {
a = i * 3;
}
} // namespace forloop
If this is unclear please let me know I'll go into more detail or explain differently.
Do not bother you with performance at first: make it safe before everything.
I would just quote Scott Meyers (Effective C++) for your concern:
"Postpone declarations as far as you can".
Thus, the second pattern is safer.
Example:
int j = 0;
for(int i = 0; i < 10000; i++){
j = 3 * i;
printf("%d",j);
}
...
// Use of j out of control!!!
int k = j * 5;
Now with the second pattern:
for(int i = 0; i < 10000; i++){
int j = 3 * i;
printf("%d",j);
}
...
// j not declared at this point.
// You get informed of the mistake at compile time, which is far much better.
int k = j * 5;
You do have a C++ tag, and you mention "declaring a string" in the question. Therefore there might be a performance difference (and yes, the printf could swamp it). Declaring a non-simple variable means calling a constructor, which might mean a non-trivial amount of work. In that case, declaring it inside of the loop could be hiding significant work in what appears to be an innocent declaration.
In general, the answer is that if you really care about performance - and treating the sample code as only an example of the difference between two places to declare a variable - then for non-simple variables, it is better to declare it outside the loop, unless the semantics require a fresh version of a temporary at each iteration.
There are likely many other places first to look at if performance is an issue, but one consideration is always moving loop invariants out of loops, especially if it is much easier for you to tell that it is invariant than for the compiler. And what looks like a declaration, can, in C++, fall into that category.
If, for (silly) example, you have
int k = 43;
for ( int i = 0; i < N; ++i )
{
int j = 17 + k; // k was previously defined outside the loop, but doesn't change in it
l = j * j; // l was also declared outside the loop
}
any good optimizing compiler can recognize that k is constant, and that j is always assigned 60, and l is assigned 3600 N times, and the loop can simply be removed and replaced with a single assignment to l. Here k and j are both loop invariants.
But a not-quite-so-good compiler might miss even one link in that chain, and wind up creating the loop.
It gets harder for the compiler to figure things out when you have
Foo k( 43 ); // a class that takes an int argument to its constructor
for( int i = 0; i < N; ++i )
{
Bar j( k ); // a Bar takes an int argument, adds 17 and stores it.
l = j.squared();
}
Same invariants. Not as easy to detect without looking inside the workings of bar; and if the constructor and squared method aren't inline, we've just made it slower.
In this case, printf("%d", i * 3) would be better than defining the variable at all.
To answer your question and not nitpicking:
The difference between the 2 variants is, that you are declaring your variable number in different "variable environments" - by which I mean that the scope changes. A variable environment is given by your curly braces { ... }. Everytime you open a new curly brace like this { ... { ... } ... }, you declare a new variable environment inside the old one, which means, that if you declare numbers like so:
{ ... { int numbers; ... } ... }
this variable will only be visible or existent in the innermost environment. So
{ ... { int numbers; ... } ... do_something(numbers); ... }
will give a compiler error.
And to your concerns about performance: Neither variant is better performing. Most, if not all compilers will give the same assembly.

Stack versus Integer

I've created a program to solve Cryptarithmetics for a class on Data Structures. The professor recommended that we utilize a stack consisting of linked nodes to keep track of which letters we replaced with which numbers, but I realized an integer could do the same trick. Instead of a stack {A, 1, B, 2, C, 3, D, 4} I could hold the same info in 1234.
My program, though, seems to run much more slowly than the estimation he gave us. Could someone explain why a stack would behave much more efficiently? I had assumed that, since I wouldn't be calling methods over and over again (push, pop, top, etc) and instead just add one to the 'solution' that mine would be faster.
This is not an open ended question, so do not close it. Although you can implement things different ways, I want to know why, at the heart of C++, accessing data via a Stack has performance benefits over storing in ints and extracting by moding.
Although this is homework, I don't actually need help, just very intrigued and curious.
Thanks and can't wait to learn something new!
EDIT (Adding some code)
letterAssignments is an int array of size 26. for a problem like SEND + MORE = MONEY, A isn't used so letterAssignments[0] is set to 11. All chars that are used are initialized to 10.
answerNum is a number with as many digits as there are unique characters (in this case, 8 digits).
int Cryptarithmetic::solve(){
while(!solved()){
for(size_t z = 0; z < 26; z++){
if(letterAssignments[z] != 11) letterAssignments[z] = 10;
}
if(answerNum < 1) return NULL;
size_t curAns = answerNum;
for(int i = 0; i < numDigits; i++){
if(nextUnassigned() != '$') {
size_t nextAssign = curAns % 10;
if(isAssigned(nextAssign)){
answerNum--;
continue;
}
assign(nextUnassigned(), nextAssign);
curAns /= 10;
}
}
answerNum--;
}
return answerNum;
}
Two helper methods in case you'd like to see them:
char Cryptarithmetic::nextUnassigned(){
char nextUnassigned = '$';
for(int i = 0; i < 26; i++) {
if(letterAssignments[i] == 10) return ('A' + i);
}
}
void Cryptarithmetic::assign(char letter, size_t val){
assert('A' <= letter && letter <= 'Z'); // valid letter
assert(letterAssignments[letter-'A'] != 11); // has this letter
assert(!isAssigned(val)); // not already assigned.
letterAssignments[letter-'A'] = val;
}
From the looks of things the way you are doing things here is quite inefficiant.
As a general rule try to have the least amount of for loops possible since each one will slow down your implementation greatly.
for instance if we strip all other code away, your program looks like
while(thing) {
for(z < 26) {
}
for(i < numDigits) {
for(i < 26) {
}
for(i < 26) {
}
}
}
this means that for each while loop you are doing ((26+26)*numDigits)+26 loop operations. Thats assuming isAssigned() does not use a loop.
Idealy you want:
while(thing) {
for(i < numDigits) {
}
}
which i'm sure is possible with changes to your code.
This is why your implementation with the integer array is much slower than an implementation using the stack which does not use the for(i < 26) loops (I assume).
In Answer to your original question however, storing an array of integers will always be faster than any struct you can come up with simply because there are more overheads involved in assigning the memory, calling functions, etc.
But as with everything, implementation is the key difference between a slow program and a fast program.
The problem is that by counting you are considering also repetitions, when may be the problem asks to assign a different number to each different letter so that the numeric equation holds.
For example for four letters you are testing 10*10*10*10=10000 letter->number mappings instead of 10*9*8*7=5040 of them (the bigger is the number of letters and bigger becomes the ratio between the two numbers...).
The div instruction used by the mod function is quite expensive. Using it for your purpose can easily be less efficient than a good stack implementation. Here is an instruction timings table: http://gmplib.org/~tege/x86-timing.pdf
You should also write unit tests for your int-based stack to make sure that it works as intended.
Programming is actually trading memory for time and vice versa.
Here you are packing data into integer. You spare memory but loose time.
Speed of course depends on the implementation of stack. C++ is C with classes. If you are not using classes it's basically C(as fast as C).
const int stack_size = 26;
struct Stack
{
int _data[stack_size];
int _stack_p;
Stack()
:_stack_size(0)
{}
inline void push(int val)
{
assert(_stack_p < stack_size); // this won't be overhead
// unless you compile debug version(-DNDEBUG)
_data[_stack_p] = val;
}
inline int pop()
{
assert(_stack_p > 0); // same thing. assert is very useful for tracing bugs
return _data[--_stack_p]; // good hint for RVO
}
inline int size()
{
return _stack_p;
}
inline int val(int i)
{
assert(i > 0 && i < _stack_p);
return _data[i];
}
}
There is no overhead like vtbp. Also pop() and push() are very simple so they will be inlined, so no overhead of function call. Using int as stack element also good for speed because int is guaranteed to be of best suitable size for processor(no need for alignment etc).

Why are empty expressions legal in C/C++?

int main()
{
int var = 0;; // Typo which compiles just fine
}
How else could assert(foo == bar); compile down to nothing when NDEBUG is defined?
This is the way C and C++ express NOP.
You want to be able to do things like
while (fnorble(the_smurf) == FAILED)
;
and not
while (fnorble(the_smurf) == FAILED)
do_nothing_just_because_you_have_to_write_something_here();
But! Please do not write the empty statement on the same line, like this:
while (fnorble(the_smurf) == FAILED);
That’s a very good way to confuse the reader, since it is easy to miss the semicolon, and therefore think that the next row is the body of the loop. Remember: Programming is really about communication — not with the compiler, but with other people, who will read your code. (Or with yourself, three years later!)
I'm no language designer, but the answer I'd give is "why not?" From the language design perspective, one wants the rules (i.e. the grammar) to be as simple as possible.
Not to mention that "empty expressions" have uses, i.e.
for (i = 0; i < INSANE_NUMBER; i++);
Will dead-wait (not a good use, but a use nonetheless).
EDIT: As pointed out in a comment to this answer, any compiler worth its salt would probably not busy wait at this loop, and optimize it away. However, if there were something more useful in the for head itself (other than i++), which I've seen done (strangely) with data structure traversal, then I imagine you could still construct a loop with an empty body (by using/abusing the "for" construct).
OK, I’ll add this to the worst case scenario that you may actually use:
for (int yy = 0; yy < nHeight; ++yy) {
for (int xx = 0; xx < nWidth; ++xx) {
for (int vv = yy - 3; vv <= yy + 3; ++vv) {
for (int uu = xx - 3; uu <= xx + 3; ++uu) {
if (test(uu, vv)) {
goto Next;
}
}
}
Next:;
}
}
I honestly don't know if this is the real reason, but I think something that makes more sense is to think about it from the standpoint of a compiler implementer.
Large portions of compilers are built by automated tools that analyze special classes of grammars. It seems very natural that useful grammars would allow for empty statements. It seems like unnecessary work to detect such an "error" when it doesn't change the semantics of your code. The empty statement won't do anything, as the compiler won't generate code for those statements.
It seems to me that this is just a result of "Don't fix something that isn't broken"...
Obviously, it is so that we can say things like
for (;;) {
// stuff
}
Who could live without that?
When using ;, please also be aware about one thing. This is ok:
a ? b() : c();
However this won't compile:
a ? b() : ; ;
There are already many good answers but have not seen the productive-environment sample.
Here is FreeBSD's implementation of strlen:
size_t
strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s)
;
return (s - str);
}
The most common case is probably
int i = 0;
for (/* empty */; i != 10; ++i) {
if (x[i].bad) break;
}
if (i != 10) {
/* panic */
}
while (1) {
; /* do nothing */
}
There are times when you want to sit and do nothing. An event/interrupt driven embedded application or when you don't want a function to exit such as when setting up threads and waiting for the first context switch.
example:
http://lxr.linux.no/linux+v2.6.29/arch/m68k/mac/misc.c#L523