Home > front end >  Semantic difference between function return and assignment
Semantic difference between function return and assignment

Time:10-02

The Standard provides an example at 6.8.6.4:

EXAMPLE In:

struct s { double i; } f(void);
union {
    struct {
        int f1;
        struct s f2;
    } u1;
    struct {
        struct s f3;
        int f4;
    } u2;
} g;
struct s f(void)
{
    return g.u1.f2;
}
/* ... */
g.u2.f3 = f();

there is no undefined behavior, although there would be if the assignment were done directly (without using a function call to fetch the value).

Could you explain why there would be UB in case of direct assignment. It seems a contradiction to what was defined above the example in the Standard:

If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.

So the semantic of return and assignments should be the same.

CodePudding user response:

The key point here is not about conversion. In the example, the value in the return statement has the same type as the function return type, so no conversion is needed.

The key point is the requirement (standard clause 6.5.16.1, paragraph 3) that assignment is only defined for overlapping objects if the overlap is exact:

If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have qualified or unqualified versions of a compatible type; otherwise, the behavior is undefined.

Hence the assignment:

g.u2.f3 = g.u1.f2;

would be undefined behavior (since the objects are "non-exactly overlapping"), but in the example the assignment happens via a function call so the assignment is not directly between non-exactly overlapping objects and thus not undefined behavior.

  • Related