是否为get_time定义了重复分配?

时间:2016-06-16 14:03:37

标签: c++ scanf undefined-behavior suppress gettime

我正在研究this answer。我遇到了一个难题:scanf has an assignment suppressing '*'

  

如果存在此选项,则该函数不会将转换结果分配给任何接收参数

但是当在get_time中使用时,'*'会在Visual Studio,libc ++和libstdc ++ str >> get_time(&tmbuf, "%T.%*Y")上产生运行时错误,因此我认为它不受支持。

因此,我选择通过两次阅读tmbuf.tm_year来忽略输入:

str >> get_time(&tmbuf, "%H:%M:%S.%Y UTC %b %d %Y");

This works似乎是get_time的唯一选择,因为'*'不被接受。但众所周知,仅仅因为它起作用并不意味着它的定义。有人可以证实:

  1. 定义为在get_time
  2. 中分配两次相同的变量
  3. 流将始终从左向右读取,因此%Y的1 st 发生率将被踩踏,而不是2 nd

1 个答案:

答案 0 :(得分:1)

该标准指定了在 22.4.5.1.1 get_time成员中处理time_get格式字符串的确切算法。 (time_get::getstr>>get_time(...)时最终被调用的内容。我引用了重要的部分:

  

该功能从评估err = ios_base::goodbit开始。然后它进入循环,在每次迭代时从s读取零个或多个字符。除非下面另有说明,否则当下列第一个条件成立时,循环终止:

     

(8.1) - 表达式fmt == fmtend的计算结果为真。

     

跳过无聊的错误处理部分

     

(8.4) - fmt的下一个元素等于’%’,可选地后跟一个修饰符,后跟一个转换说明符字符,格式,一起形成一个对ISO有效的转换规范/ IEC 9945函数strptime跳过无聊的错误处理部分该函数评估s = do_get(s, end, f, err, t, format, modifier) 跳过更多无聊的错误处理部分函数递增fmt指向刚刚结束的转换规范并继续循环。

从描述中可以看出,格式字符串从左到右严格顺序处理。没有专门处理重复转换规范的规定。所以答案肯定是肯定的,你所做的就是定义明确,完全合法。