This program is an exhibit of undefined behavior: when the declaration of the struct
in one translation unit does not match its definition in the other translation unit, the program is ill-defined, and it can do anything.
In this case, you got lucky, and the program printed numbers in the opposite order. Although it did it on your system, there is no requirement for your program to do the same (or even to run!) on another standard-compliant system. This is because the types of fields match pairwise (j
<==> i
, k
<===> j
, i
and <===> k
). If you change the types of i
, j
, and k
to char
, double
, and int
, your program will probably print some garbage values or crash.
From C99, 6.2.7.1:
two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are complete types, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types, and such that if one member of a corresponding pair is declared with a name, the other member is declared with the same name. For two structures, corresponding members shall be declared in the same order. For two structures or unions, corresponding bit-fields shall have the same widths. For two enumerations, corresponding members shall have the same values. (emphasis added)