Will strlen be calculated multiple times if used i

2019-01-16 07:46发布

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
}

Will strlen() be calculated every time when i increases?

18条回答
一纸荒年 Trace。
2楼-- · 2019-01-16 08:13

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.

查看更多
姐就是有狂的资本
3楼-- · 2019-01-16 08:14

If ss is of type const char * and you're not casting away the constness within the loop the compiler might only call strlen once, if optimizations are turned on. But this is certainly not behavior that can be counted upon.

You should save the strlen result in a variable and use this variable in the loop. If you don't want to create an additional variable, depending on what you're doing, you may be ale to get away with reversing the loop to iterate backwards.

for( auto i = strlen(s); i > 0; --i ) {
  // do whatever
  // remember value of s[strlen(s)] is the terminating NULL character
}
查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-16 08:14

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.

查看更多
SAY GOODBYE
5楼-- · 2019-01-16 08:16

Arrgh, it will, even under ideal circumstances, dammit!

As of today (January 2018), and gcc 7.3 and clang 5.0, if you compile:

#include <string.h>

void bar(char c);

void foo(const char* __restrict__ ss) 
{
    for (int i = 0; i < strlen(ss); ++i) 
    {
        bar(*ss);
    }
}    

So, we have:

  • ss is a constant pointer.
  • ss is marked __restrict__
  • The loop body cannot in any way touch the memory pointed to by ss (well, unless it violates the __restrict__).

and still, both compilers execute strlen() every single iteration of that loop. Amazing.

This also means the allusions/wishful thinking of @Praetorian and @JaredPar doesn't pan out.

查看更多
神经病院院长
6楼-- · 2019-01-16 08:20

Yes, the strlen() function is called every time the loop is evaluated.

If you want to improve the efficiency then always remember to save everything in local variables... It will take time but it's very useful ..

You can use code like below:

String str="ss";
int l = strlen(str);

for ( int i = 0; i < l ; i++ )
{
    // blablabla
}
查看更多
干净又极端
7楼-- · 2019-01-16 08:24

Yes, strlen() will be evaluated on each iteration. It's possible that, under ideal circumstances, the optimiser might be able to deduce that the value won't change, but I personally wouldn't rely on that.

I'd do something like

for (int i = 0, n = strlen(ss); i < n; ++i)

or possibly

for (int i = 0; ss[i]; ++i)

as long as the string isn't going to change length during the iteration. If it might, then you'll need to either call strlen() each time, or handle it through more complicated logic.

查看更多
登录 后发表回答