Will strlen be calculated multiple times if used in a loop condition?

后端 未结 18 1689
再見小時候
再見小時候 2020-12-07 15:10

I\'m not sure if the following code can cause redundant calculations, or is it compiler-specific?

for (int i = 0; i < strlen(ss); ++i)
{
    // blabla
}
<         


        
相关标签:
18条回答
  • Not common nowadays but 20 years ago on 16 bit platforms, I'd recommend this:

    for ( char* p = str; *p; p++ ) { /* ... */ }
    

    Even if your compiler isn't very smart in optimization, the above code can result in good assembly code yet.

    0 讨论(0)
  • 2020-12-07 15:45

    YES, in simple words. And there is small no in rare condition in which compiler is wishing to, as an optimization step if it finds that there is no changes made in ss at all. But in safe condition you should think it as YES. There are some situation like in multithreaded and event driven program, it may get buggy if you consider it a NO. Play safe as it is not going to improve the program complexity too much.

    0 讨论(0)
  • 2020-12-07 15:47

    The predicate code in it's entirety will be executed on every iteration of the for loop. In order to memoize the result of the strlen(ss) call the compiler would need to know that at least

    1. The function strlen was side effect free
    2. The memory pointed to by ss doesn't change for the duration of the loop

    The compiler doesn't know either of these things and hence can't safely memoize the result of the first call

    0 讨论(0)
  • 2020-12-07 15:47

    We can easily test it :

    char nums[] = "0123456789";
    size_t end;
    int i;
    for( i=0, end=strlen(nums); i<strlen(nums); i++ ) {
        putchar( nums[i] );
        num[--end] = 0;
    }
    

    Loop condition evaluates after each repetition, before restarting the loop .

    Also be careful about the type you use to handle length of strings . it should be size_t which has been defined as unsigned int in stdio. comparing and casting it to int might cause some serious vulnerability issue.

    0 讨论(0)
  • 2020-12-07 15:47

    Elaborating on Prætorian's answer I recommend the following:

    for( auto i = strlen(s)-1; i > 0; --i ) {foo(s[i-1];}
    
    • auto because you don't want to care about which type strlen returns. A C++11 compiler (e.g. gcc -std=c++0x, not completely C++11 but auto types work) will do that for you.
    • i = strlen(s) becuase you want to compare to 0 (see below)
    • i > 0 because comparison to 0 is (slightly) faster that comparison to any other number.

    disadvantage is that you have to use i-1 in order to access the string characters.

    0 讨论(0)
  • 2020-12-07 15:48

    Yes. The test doesn't know that ss doesn't get changed inside the loop. If you know that it won't change then I would write:

    int stringLength = strlen (ss); 
    for ( int i = 0; i < stringLength; ++ i ) 
    {
      // blabla 
    } 
    
    0 讨论(0)
提交回复
热议问题