scanf中有保证的分配顺序吗?

时间:2019-05-01 06:58:08

标签: c++ scanf language-lawyer cstdio

我遇到了一些代码,想知道它只是按预期运行还是偶然,还是不好的做法。 考虑以下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。我不是。

1 个答案:

答案 0 :(得分:3)

您在N4810中没有提到任何内容,因为涉及到C标准库时,该规范大部分都遵循“ ISO / IEC 9899:2011,编程语言— C” 。如果我们看一下N1570(C11草案),它是关于scanf的。 功能家族:

  

7.21.6.2 fscanf函数(强调我的意思)

     

10除非有%说明符,否则输入项(或   如果是%n指令,则输入字符数为)   转换为适合转换说明符的类型。如果   输入项不是匹配序列,指令的执行   失败:此条件是匹配失败。除非分配   抑制由*表示,转换结果为   放在第一个参数所指向的对象之后   尚未收到转换结果的format参数。   如果此对象的类型不合适,或者如果转换结果无法在该对象中表示,则行为   未定义

因此,您的示例工作确实是偶然行为,它是由于不确定的行为而产生的。