Question

Can I use strlen of a const char* in a loop like this and expect O(n) time complexity, or would it result in O(n^2)? I think it looks cleaner than using a variable for the string length.

void send_str( const char* data ) {
    for (uint8_t i = 0; i < strlen(data); i++)
        send_byte( data[i] );
}

Does it depend on the optimization level?

Was it helpful?

Solution

I don't think you can ever depend on an optimization happening.

Why not do it like this, if you really want to avoid an extra variable:

void send_str(const char *data)
{
  for(size_t i = strlen(data); i != 0; --i)
    send_byte(*data++);
}

Or, less silly, and more like an actual production-quality C program:

void send_str(const char *data)
{
  while(*data != '\0')
    send_byte(*data++);
}

There's no point at all in iterating over the characters twice, so don't call strlen() at all, detect the end-of-string yourself.

OTHER TIPS

The compiler might optimize that, but perhaps not to the point you want it to. Obviously depending on the compiler version and the optimization level.

you might consider using the MELT probe to understand what GCC is doing with your code (e.g. what internal Gimple representation is it transformed to by the compiler). Or gcc -fverbose-asm -O -S to get the produced assembler code.

However, for your example, it is simpler to code:

 void send_str(const char*data) {
    for (const char*p = data; *p != 0; p++)
        send_byte(*p);
 }

If the definition of send_byte() is not available when this code is compiled (eg. it's in another translation unit), then this probably can't be optimised in the way you describe. This is because the const char * pointer doesn't guarantee that the object pointed to really is const, and therefore the send_byte() function could legally modify it (send_byte() may have access to that object via a global variable).

For example, were send_byte() defined like so:

int count;
char str[10];

void send_byte(char c)
{
    if (c == 'X')
        str[2] = 0;
    count++;
}

and we called the provided send_str() function like so:

count = 0;
strcpy(str, "AXAXAX");
send_str(str);

then the result in count must be 2. If the compiler hoisted the strlen() call in send_str() out of the loop, then it would instead be 6 - so this would not be a legal transform for the compiler to make.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top