Magmurrr
Magmurrr

Reputation: 248

C for loop optimisation by embedding statements into loop-head itself

Just wondering if these variations of for loops are more efficient and practical. By messing with the c for loop syntax i can embedd statements that would go in the loop-body into the loop-head like so:

Example 1:

#include <stdio.h>
int main(int argc, char ** argv)
{
    // Simple program that prints out the command line arguments passed in
    if (argc > 1)
    {
        for(int i = 1; puts(argv[i++]), i < argc;);

        // This does the same as this:
        // for(int i = 1; i < argc; i++)
        // {
        //  puts(argv[i]);
        // }
    }

    return 0;
}

I understand how the commas work in the for loop it goes through each statement in order, evaluates them then disregards all but the last one which is why it is able to iterate using the "i < argc"condition. There is no need for the final segment to increment the i variable as i did that in the middle segment of the loop head (in the puts(argv[i++]) bit). Is this more efficient or is just just cleaner to seperate it into the loop body rather than combine it all into one line?

Example 2:

int stringLength(const char * string)
{
    // Function that counts characters up until null terminator character and returns the total
    int counter = 0;
    for(counter; string[counter] != '\0'; counter++);
    return counter;
    // Same as:
    //int counter = 0;
    // for(int i = 0; string[i] != '\0'; i++)
    //{
    //  counter++;
    //}
    //return counter;
}

This one seems more efficient than the version with the loop body as no local variable for the for-loop is initialised. Is it conventional to do these sorts of loops with no bodies?

Upvotes: 1

Views: 137

Answers (1)

chux
chux

Reputation: 153517

Step 1: Correctness

Make sure code is correct.

Consider OP's code below. Does it attempt to print argv[argc] which would be bad?

if (argc > 1) {
    for(int i = 1; puts(argv[i++]), i < argc;);

I initially thought it did. So did another user. Yet it OK.
… and this is exactly why code is weak.

Code not only should be correct, better code looks correct too. Using an anti-pattern as suggested by OP is rarely1 as good thing.


Step 2: Since code variations have the same big O, focus on understandably.

Sculpt your code – remove what is not needed.

for (int i = 1; i < argc; i++) {
  puts(argv[i]);
}

What OP is doing is a trivial optimization concern.
Is premature optimization really the root of all evil?


Is it conventional to do these sorts of loops with no bodies?

Not really.

The key to the style of coding is to follow your group's style guide. Great software is often a team effort. If your group's likes to minimize bodies, go ahead. I have seen the opposite more common, explicit { some_code } bodies.


Note: int stringLength(const char * string) fails for strings longer than INT_MAX. Better to use size_t as the return type – thus an example of step 1 faltering.


1 All coding style rules, except this rule, have exceptions.

Upvotes: 5

Related Questions