<div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">The code has:</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">tm = *t;</span><br style="font-family:Arial,Helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">mkt = mktime(&tm);</span><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br></span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">This makes a copy of the `const struct tm` that is the argument to strftime(), and passes that copy to mktime(), which reads a few fields and sets most fields.  But since it is working on a copy of the argument to strftime(), I don't see a problem.  Can you elaborate?</span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br></span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">Is there a good reason not to write this?<br><br></span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">struct tm tm = *t;</span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">time_t mkt = mktime(&tm);</span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br></span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">It's a stylistic question wholly separate from the const-ness issue.</span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Nov 8, 2022 at 6:07 AM Robert Elz via tz <<a href="mailto:tz@iana.org">tz@iana.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The code for the %s strftime conversion starts as:<br>
(this taken from tzcode2022f strftime.c - but I suspect<br>
that many versions are the same)<br>
<br>
                        case 's':<br>
                                {<br>
                                        struct tm       tm;<br>
                                        char            buf[INT_STRLEN_MAXIMUM(<br>
                                                                time_t) + 1];<br>
                                        time_t          mkt;  <br>
<br>
                                        tm = *t;<br>
                                        mkt = mktime(&tm);<br>
<br>
The "tm = *t;" line is the problem.   It (or more correctly, something<br>
to replace that) is needed, as *t is const, strftime() is not permitted<br>
to modify it, yet the struct tm * passed to mktime() is not const, as<br>
mktime is sometimes required to modify that struct before returning.<br>
<br>
However, mktime() refers only to the fields tm_year tm_mon tm_mday<br>
tm_hour tm_min tm_sec and tm_isdst of the struct passed to it.  The<br>
%s conversion is defined as producing (in a decimal string format) the<br>
result of mktime() applied to the struct tm passed to strftime.<br>
Hence an application which intends to use strftime(..., "%s", ...)<br>
need only initialise those 7 fields, the other 2 (currently) standard<br>
fields (tm_yday and tm_wday) are explicitly ignored by mktime() on<br>
input, so there is no need to assign those values, and any other<br>
fields that might exist in a particular implementation are out of<br>
scope for a portable (conforming) application to touch, so cannot<br>
be initialised.<br>
<br>
Since referring to an uninitialised variable is, I believe, technically<br>
undefined behaviour, doing a struct copy (copying all fields) can have<br>
that effect.   (An application could memset() the entire struct before<br>
providing the values it must add, but is not required to do that).<br>
<br>
It seems likely that the simple fix is to replace the struct assignment<br>
with 7 individual assignment statements<br>
<br>
        tm.tm_year = t->tm_year;<br>
        tm.tm_mon = t->tm_mon;<br>
        /* ... */<br>
<br>
On the other hand, hardware that balks at simply loading or copying,<br>
uninitialised values, without using them for any purpose is not exactly<br>
common (and half the world's code would probably break if an implementation<br>
that worked in such a manner was ever created) so I'd call this one of<br>
the less significant issues to worry about fixing.<br>
<br>
kre<br>
<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr">Jonathan Leffler <<a href="mailto:jonathan.leffler@gmail.com" target="_blank">jonathan.leffler@gmail.com</a>>  #include <disclaimer.h><br>Guardian of DBD::Informix - v2018.1031 - <a href="http://dbi.perl.org" target="_blank">http://dbi.perl.org</a><br>"Blessed are we who can laugh at ourselves, for we shall never cease to be amused."</div></div></div></div></div></div></div></div></div></div>