From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id A10823858C2D; Fri, 10 Feb 2023 08:33:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A10823858C2D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676018023; bh=wakOC7swjNOTruJQOZ6nvovkOaU7Iwjz++TJyxh5y+Y=; h=From:To:Subject:Date:In-Reply-To:References:From; b=u1Ip1gg4y2wl3I4JAYwkfxw/YtImRk+qCNnNmhNjTykLkdyVYKMPGfuRS5PlyhM3X 8mVM4RPZDtHvRGqhU0sKKludBLnxnnWF4Bnmf4KOV/WUykarsOjxGeOsGdF0mQLKai VOtCwCtFjABatcIOP9GcH7wBCTMojbobd7xGMCeI= From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/77760] get_time needs to set tm_wday amd tm_yday Date: Fri, 10 Feb 2023 08:33:31 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 7.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D77760 --- Comment #7 from Jakub Jelinek --- (In reply to Alexandre Oliva from comment #5) > As for tm bits, my suggestion was to overwrite tm fields internally, not = to > expose that externally. They'd be used as scratch bits. As in, member > functions in the public interface would not use incoming tm bits as > __time_get_state, but rather a zeroed-out __time_get_state structure, as > today, but when calling the internal implementation primitive do_get, the= y'd > *blindly* *overwrite* some of the tm bits with those from __time_get_stat= e, > and when do-get returns, they'd pull them back into __time_get_state and = out > of tm. They'd be used as scratch bits, which AFAICT is permissible.=20 > do_get, being protected and thus more of an internal implementation bit, > could make use of those scratch bits. do_get overriders could tweak them, > for better or worse, but since this use would be nonstandard, we could > probably get away with assuming any such uses to be libstdc++-specific. = It > would probably not be wise for users to rely on this internal extension, > though, since one can hope the standard will eventually make room for an > implementation of time_get that is both standard-compliant and compatible > with reasonable strptime expectations. If all users would initialize struct tm to zeros before calling the APIs, t= hen I can understand that it would work (but still libstdc++ would need to know which of the calls are nested and which are the outermost, so that they'd finalize the state before leaving the outermost method back to canonical fo= rm). But if some fields can be uninitialized, I really don't understand how you could use them as scratch bits, they could have random values upon entering= the outermost method. I don't know if C++ says anything about the prior content of struct tm (but given the recursive processing of some format specifiers it is hard to imag= ine they'd e.g. clear the whole struct), for strptime POSIX manpage says: "It is unspecified whether multiple calls to strptime() using the same tm structure will update the current contents of the structure or overwrite all contents of the structure. Conforming applications should make a single cal= l to strptime() with a format and all data needed to completely specify the date= and time being converted." and the Linux manpage: "In principle, this function does not initialize tm but stores only the val= ues specified. This means that tm should be initialized before the call. Details differ a bit between different UNIX systems. The glibc implementation does = not touch those fields which are not explicitly specified, except that it recomputes the tm_wday and tm_yday field if any of the year, month, or day elements changed." Now, if even the POSIX manpage shows in an example a case where struct tm i= sn't zeroed out before calling it (but has format specifiers to initialize everything).=