1

In general I know why you get this error, but I'm a little confused in this particular instance...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* mystrncpy(char* dst, const char* src, size_t n) {
    char* temp = dst;

    while (n-- > 0 && (*temp = *src)) {
        temp++;
        src++;
    }

    return dst;
}

int main() {
    const char* str = "Hello World!";
    char buf[50];
    memset(buf, 0, sizeof(buf));
    mystrncpy(buf, str, sizeof(buf));
    printf("%s\n", buf);
}

The code above works great, but if I remove the extra set of brackets changing the while loop to:

while (n-- > 0 && *temp = *src)

Then I get the error. I guess it's something about operator precedence but I'm a little baffled. Can someone explain what that while loop alteration does to make this compiler error appear?

3
  • 4
    If you already suspect operator precedence issues, what's stopping you from looking up the precedence rules of the operators in your expression?
    – Kerrek SB
    Commented Jan 16, 2012 at 18:38
  • @KerrekSB sometimes a push goes a long way :).
    – JonH
    Commented Jan 16, 2012 at 18:41
  • 1
    Honestly, I'm very accustomed to C++ and find sometimes that when I look at real C code I take some things for granted, so I just prefer to ask in case there's any "extra tidbits" I might miss by making an assumption. For example, the whole concept of how to use the struct keyword in C was messing with my mind recently - and how you can typedef a struct with the same name as the struct without a conflict arising. Commented Jan 16, 2012 at 18:43

5 Answers 5

5

Yes, it's about precedence.

= has lower precedence than &&. Therefore, the latter case parses as:

while ((n-- > 0 && *temp) = *src)

And of course (n-- > 0 && *temp) is not an l-value.

Are you sure you didn't intend to use == instead of =?

1
  • 1
    I agree with the answer but yes he should use = as he is assigning characters not comparing them. Still I think your intention is to explain the issue so +1.
    – JonH
    Commented Jan 16, 2012 at 18:40
4
    n-- > 0 && *temp = *src
                           =
                          / \
                         &&  *src
                        /  \
                       >    *temp
                      / \
                    n--  0
1
  • Thank you -- Don't be afraid of using too many parenthesis :)
    – pmg
    Commented Jan 16, 2012 at 18:49
2

Assignment has very low precedence, so

n-- > 0 && *temp = *src

is equivalent to

(n-- > 0 && *temp) = *src

which isn't valid C.

0

Operator precedence. The && operator is in position 13 and = is 16.

0

The assignment operator has really low precedence, so it's like you're trying to assign to the result of n-- > 0 && *temp, which is obviously not an lvalue.

Not the answer you're looking for? Browse other questions tagged or ask your own question.