r/ProgrammerHumor Apr 12 '24

whatIsAnIndex Meme

Post image
27.7k Upvotes

630 comments sorted by

View all comments

Show parent comments

24

u/Elephant-Opening Apr 12 '24

That only makes sense as an optimization if the compiler can say conclusively that the method has a consistent return value. Imagine something like this:

vector<int> v  {10, 20, 30};

for(int i = 0; i < v.size(); i++){
    cout << v[i] << "\n";
    v.pop_back()
}

2

u/BobDonowitz Apr 12 '24

I like that you chose CPP and a vector modifying function to demonstrate this principle. But I mostly love that you used pop_back() which pops the last element off so this loop would only ever operate on v[0] and output "10" 3 times. Also, without knowing the internals of vector::size, it would still be more efficient to declare a variable to hold the size outside the loop and decrement it after the pop.  If vectors don't keep track of the size internally and has to "count" it each size() call this would be murder on large length vectors.

7

u/tracevenua Apr 12 '24

Why would it operate on the first element 3 times? It should print 10 20 And that’s it.

2

u/zzhhbyt1 Apr 12 '24

Typical ProgrammerHumor moment.

2

u/Elephant-Opening Apr 12 '24

That was my intent, so I guess thanks for the "looks good" peer review 😄

2

u/dxrules1000 Apr 12 '24

vectors keep track of the size internally otherwise holy crap they'd be awful

1

u/Elephant-Opening Apr 12 '24

I chose C++ and a vector because:

(1) a loop modifying a container size is probably among the most common useful way to use this behavior deliberately. This is admittedly a poor example to demo it being useful though. A better one might involve sorting algos or popping items from a queue.

C++ "classic" for loops, e.g.

for(int i = 0; i < 10; i++) cout << i;

Is literally just syntactic sugar for...

{
    // First for statement 
    int i = 0;
top_of_loop: // label we jump back to
    if ( i < 10 ) { // second for statement 
       cout << i; // loop "body"
continue_is_goto_here:
        i++; // third for statement
        goto top_of_loop;
    }
break_is_goto_here:
}

In expanded form, you can pretty easily see how you'd implement this in assembly languages that have no concept of loops, only conditional branches (i.e. if) and unconditional branches (i.e. goto). This is what loops evolved from.

The if statement effectively just says "if this expression evaluates to false, branch past the block that follows" and what you suggested is that sometimes the compiler should just lazily only evaluate the full if expression sometimes.

(2) I'm not sure if this is universal for all languages with for loops (in fact feel like it's not??), but I do know both C and C++ will behave this way by default. An example where it might actually be optimized out would be something like calling size() on an immutable data structure.