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 */

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

  1. A.

    (1, 1)

  2. B.

    (3, 2)

  3. C.

    (1, 2)

  4. D.

    (4, 4)

Attempted by 131 students.

Show answer & explanation

Correct answer: C

Concept. Two independent C rules govern this item. (1) Pointer subtraction between two pointers into the same array yields the difference in ELEMENT count, not bytes: for T *p, *q, q - p equals the number of array elements between them. (2) A member's offset inside a struct is fixed by the LAYOUT of the members that precede it; a union member occupies the size (and alignment) of its largest member, and any tail padding that rounds the whole struct up to its alignment is placed AFTER the last member, so it cannot shift an earlier member's offset.

Application. Apply each rule to S on this 32-bit target where sizeof(S) = 4.

  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). This expression is exactly 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: Mppsc Assistant Professor