0

I was working on this answer. And I ran into a conundrum: scanf has an assignment suppressing '*':

If this option is present, the function does not assign the result of the conversion to any receiving argument

But when used in get_time the '*' gives a run-time error on Visual Studio, libc++, and libstdc++: str >> get_time(&tmbuf, "%T.%*Y") so I believe it's not supported.

As such I chose to ignore input by reading into tmbuf.tm_year twice:

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

This works and seems to be my only option so far as get_time goes since the '*' isn't accepted. But as we all know, just because it works doesn't mean it's defined. Can someone confirm that:

  1. It is defined to assign the same variable twice in get_time
  2. The stream will always be read left-to-right so the 1stincidence of %Y will be stomped, not the 2nd
Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • 1
    `get_time` has nothing to do with `scanf`. What makes you think any of `scanf` rules apply to `get_time`? As for validity of repeated assignment, the standard doesn't say it is invalid, and it also specifies that format elements are processed one by one left to right. In fact it specifies the exact algorithm of processing the format string. The algorithm handles such cases with no error. – n. m. could be an AI Jun 16 '16 at 14:41
  • @n.m. I'm going to go with wistful thinking as the answer to your question. But sounds as though this is safe? Perhaps you'd be inspired to type that into an answer? – Jonathan Mee Jun 16 '16 at 14:44

1 Answers1

1

The standard specifies the exact algorithm of processing the format string of get_time in 22.4.5.1.1 time_get members. (time_get::get is what eventually gets called when you do str>>get_time(...)). I quote the important parts:

The function starts by evaluating err = ios_base::goodbit. It then enters a loop, reading zero or more characters from s at each iteration. Unless otherwise specified below, the loop terminates when the first of the following conditions holds:

(8.1) — The expression fmt == fmtend evaluates to true.

skip boring error-handling parts

(8.4) — The next element of fmt is equal to ’%’, optionally followed by a modifier character, followed by a conversion specifier character, format, together forming a conversion specification valid for the ISO/IEC 9945 function strptime. skip boring error-handling parts the function evaluates s = do_get(s, end, f, err, t, format, modifier) skip more boring error-handling parts the function increments fmt to point just past the end of the conversion specification and continues looping.

As can be seen from the description, the format string is processed strictly sequentially left to right. There's no provision to handle repeating conversion specifications specially. So the answer must be yes, what you have done is it is well defined and perfectly legal.

Community
  • 1
  • 1
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243