chu*_*ica 15 c restrict language-lawyer
以下代码是否定义良好?
#include <stdio.h>
int ScanFirstOrSecond(const char *s, int *dest) {
    return sscanf(s, "%d%d", dest, dest);
}
int main(void) {
    int x = 4;
    ScanFirstOrSecond("5", &x);
    printf("%d\n", x);  // prints 5
    // Here is the tricky bit
    ScanFirstOrSecond("6 7", &x);
    printf("%d\n", x);  // prints 7
    return 0;
}
换句话说,这些...论点是否暗示restrict了它们?
我发现最适用的C规范是
fscanf函数依次执行格式的每个指令.......C11dr§7.21.6.24
chq*_*lie 11
简短的回答是:是的,定义如下:
scanf将尝试将一个字节序列转换stdin为基数为10的整数,并带有可选的初始空格和一个可选的符号.如果成功,该号码将被存储x.scanf然后将再次执行这些步骤.返回值可以是EOF,0,1或2,对于后者2,转换的最后一个号码将已被存入x.
冗长的答案有点夸张:
似乎C标准确实指定值以格式字符串的顺序存储.引用C11标准:
7.21.6.2
fscanf功能...
4该
fscanf函数依次执行格式的每个指令.当所有指令都已执行,或者指令失败时(如下所述),函数返回....
7作为转换规范的指令定义了一组匹配的输入序列,如下面针对每个说明符所述.转换规范按以下步骤执行:
...
10除了在A的情况下
%说明符,输入项(或者,在A的情况下%n的指令,输入字符的计数)被转换成适合于该转换说明一种类型.如果输入项不是匹配序列,则指令的执行失败:此条件是匹配失败.除非由a指示赋值抑制,否则*转换的结果将放在由尚未收到转换结果的format参数后面的第一个参数指向的对象中....
16 如果在第一次转换(如果有)完成之前发生输入故障,该
fscanf函数将返回宏的值EOF.否则,该函数返回分配的输入项的数量,如果早期匹配失败,则可以少于提供的数量,甚至为零.
本规范中的任何其他地方都没有对提到的输出对象的任何访问.
然而,标准的措辞似乎表明,如果2个指针指向同一个对象,则行为可能是意外的:转换的结果放在第一个参数指向的对象之后,该参数在格式参数之后尚未收到转换结果.  这句话有些含糊不清:尚未收到转换结果的是什么?对象或论点?对象接收转换结果,而不是指针参数.在您的扭曲示例中,对象x已经收到了转换结果,因此它不应该接收另一个...但正如supercat所指出的,这种解释具有明显的限制性,因为它意味着所有转换后的值都存储在第一个目标对象中.
因此,它看起来完全明确并且定义明确,但可以完善规范的措辞以消除潜在的歧义.