Consider the following C code fragment running on a 32-bit x86 machine:…

2019

Consider the following C code fragment running on a 32-bit x86 machine:

typedef struct {
    union {
        unsigned char a;
        unsigned short b;
    } U;
    unsigned char c;
} S;

S B[10];
S *p = &B[4];
S *q = &B[5];
p->U.b = 0x1234;

/* structure S takes 32 bits */

Assume the conventional 32-bit x86 ILP32 ABI: unsigned short is 2 bytes with 2-byte alignment, pointers and int are 32 bits, pointer-to-int conversion preserves the numerical address, and the displayed integer subtraction does not overflow.

If M is the value of q - p and N is the value of ((int)&(p->c)) - ((int)p), then (M, N) is:

Answer: C. (1, 2)Concept. Two independent C rules govern this item. Pointer subtraction between two pointers into the same array yields the difference in element count, not…

  1. A.

    (1, 1)

  2. B.

    (3, 2)

  3. C.

    (1, 2)

  4. D.

    (4, 4)

Attempted by 174 students.

Show answer & explanation

Correct answer: C

Concept. Two independent C rules govern this item.

  • Pointer subtraction between two pointers into the same array yields the difference in element count, not bytes.

  • A member offset is determined by the layout, size, and alignment of preceding members; tail padding after the last member cannot shift an earlier member.

Application. Apply each rule to S on this 32-bit target where sizeof(S) = 4. The explicit ILP32 assumptions also make the two pointer-to-int conversions preserve their numerical addresses for this subtraction.

  1. Compute M = q - p. Here p = &B[4] and q = &B[5] point to consecutive elements of the same array B, so the element-count difference is M = 1 (the byte gap of sizeof(S) divided by sizeof(S), which is exactly the rule above).

  2. Lay out S. The union U holds an unsigned char (1 byte) and an unsigned short (2 bytes); a union's size is its largest member, so sizeof(U) = 2, occupying bytes 0 and 1 at offset 0.

  3. Place c. The next member unsigned char c follows U at the next free byte, so c sits at byte offset 2.

  4. Compute N = ((int)&(p->c)) - ((int)p). Under the stated address-preserving ILP32 assumptions, subtracting the converted numerical addresses yields the byte offset of c within S, which is N = 2.

Cross-check. The struct is rounded up to sizeof(S) = 4 for alignment; that 1 byte of tail padding sits AFTER c (byte 3). Pointer subtraction counts elements, so the padded sizeof(S) is what makes the stride exactly one element and never alters c's offset of 2. Writing p->U.b = 0x1234 only stores bytes into the union and, with endianness, never moves a member offset. Both rules therefore give (M, N) = (1, 2).

Note. The line S B[10]; is an array declaration, not an assignment, so the absence of = is correct.

A video solution is available for this question — log in and enroll to watch it.

Explore the full course: Tpsc Assistant Technical Officer

Loading lesson…