Is memcpy of a pointer the same as assignment?

前端 未结 9 1052
你的背包
你的背包 2020-12-03 16:23

Introduction: This question is part of my collection of C and C++ (and C/C++ common subset) questions regarding the cases where pointers object with strictly ide

9条回答
  •  长情又很酷
    2020-12-03 17:10

    Prior to C99, implementations were expected to behave as though the value of every variable of any type was stored a sequence of unsigned char values; if the underlying representations of two variables of the same type were examined and found to be equal, that would imply that unless Undefined Behavior had already occurred, their values would generally be equal and interchangeable. There was a little bit of ambiguity in a couple places, e.g. given

    char *p,*q;
    p = malloc(1);
    free(p);
    q = malloc(1);
    if (!memcmp(&p, &q, sizeof p))
      p[0] = 1;
    

    every version of C has made abundantly clear that q may or may not equal to p, and if q isn't equal to p code should expect that anything might happen when p[0] is written. While the C89 Standard does not explicitly say that an implementation may only have p compare bitwise equal to q if a write to p would be equivalent to a write to q, such behavior would generally be implied by the model of variables being fully encapsulated in sequences of unsigned char values.

    C99 added a number of situations where variables may compare bitwise equal but not be equivalent. Consider, for example:

    extern int doSomething(char *p1, char *p2);
    int act1(char * restrict p1, char * restrict p2)
      { return doSomething(p1,p2); }
    int act2(char * restrict p)
      { return doSomething(p,p); }
    int x[4];
    int act3a(void) { return act1(x,x); }
    int act3b(void) { return act2(x); }
    int act3c(void) { return doSomething(x,x); }
    

    Calling act3a, act3b, or act3c will cause doSomething() to be invoked with two pointers that compare equal to x, but if invoked through act3a, any element of x which is written within doSomething must be accessed exclusively using x, exclusively using p1, or exclusively using p2. If invoked through act3b, the method would gain the freedom to write elements using p1 and access them via p2 or vice versa. If accessed through act3c, the method could use p1, p2, and x interchangeably. Nothing in the binary representations of p1 or p2 would indicate whether they could be used interchangeably with x, but a compiler would be allowed to in-line expand doSomething within act1 and act2 and have the behavior of those expansions vary according to what pointer accesses were allowed and forbidden.

提交回复
热议问题