scanf 中是否有保证的分配顺序?

Is there a guaranteed order of assignment in scanf?

我遇到了一些代码,想知道它是否按预期工作只是侥幸,还是只是不好的做法。 考虑以下 MCVE (ideone):

#include <cstdio>

struct dummyStruct
{
    unsigned short min[4];
    unsigned short max[4];
    int            dummyBuffer; // This just happens to be here as a real variable in the original code, not just as a buffer.
};


int main()
{
    dummyStruct db;
    // Note that the size of the short is assumed to be half of that of the %d specifier
    sscanf("  123,   456,  789,   112", "%d, %d, %d, %d", db.min+0, db.min+1, db.min+2, db.min+3);
    sscanf("29491, 29491, 29491, 29491", "%d, %d, %d, %d", db.max+0, db.max+1, db.max+2, db.max+3);
    db.dummyBuffer = 1234;
    printf("%hd, %hd, %hd, %hd\n", db.min[0], db.min[1], db.min[2], db.min[3]);
    printf("%hd, %hd, %hd, %hd\n", db.max[0], db.max[1], db.max[2], db.max[3]);
    printf("%d\n", db.dummyBuffer);

    return 0;
}

标准保证结构的内容,还是这种未定义的行为?我在 N4810 中没有看到这一点。 或者,如果我们颠倒变量的顺序,例如

printf("%hd, %hd, %hd, %hd\n", db.min[0], db.min[2], db.min[1], db.min[3]);

db.min的内容有保证吗?参数的顺序(从左到右)是赋值的顺序吗?另请注意,即使已定义,我也不是在问为什么这是不好的做法。我也不需要评论告诉我不要使用 scanf。我不是。

您没有在 N4810 中看到任何提及,因为当涉及到 C 标准库时,规范大部分被推迟到 "ISO/IEC 9899:2011, Programming languages — C"。如果我们看一下 N1570(C11 草案),它是关于 scanf 的 函数族:

7.21.6.2 The fscanf function (emphasis mine)

10 Except in the case of a % specifier, the input item (or, in the case of a %n directive, the count of input characters) is converted to a type appropriate to the conversion specifier. If the input item is not a matching sequence, the execution of the directive fails: this condition is a matching failure. Unless assignment suppression was indicated by a *, the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result. If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behavior is undefined.

所以你的样本工作确实是一个未定义行为的侥幸。