[gcc r15-8979] libstdc++: Use const_cast to workaround tm_zone being non-const

Jonathan Wakely redi@gcc.gnu.org
Thu Mar 27 15:29:05 GMT 2025


https://gcc.gnu.org/g:16766d5a0c4a946d3ba9255a99621975b9773e18

commit r15-8979-g16766d5a0c4a946d3ba9255a99621975b9773e18
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Mar 26 17:45:06 2025 +0000

    libstdc++: Use const_cast to workaround tm_zone being non-const
    
    Iain reported that he's seeing this on Darwin:
    
    include/bits/chrono_io.h:914: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
    
    This is because the BSD definition ot tm::tm_zone is a char* (and has
    been since 1987) rather than const char* as in Glibc and POSIX.1-2024.
    
    We can fix it by using const_cast<char*> when setting the tm_zone
    member. This should be safe because libc doesn't actually write anything
    to tm_zone; it's only non-const because the BSD definition predates the
    addition of the const keyword to C.
    
    For targets where it's a const char* the cast won't matter because it
    will be converted back to const char* on assignment anyway.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/chrono_io.h (__formatter_chrono::_M_c): Use
            const_cast when setting tm.tm_zone.
    
    Reviewed-by: Iain Sandoe <iain@sandoe.co.uk>

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index 08969166d2f7..c55b651d0491 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -907,21 +907,22 @@ namespace __format
 
 #ifdef _GLIBCXX_HAVE_STRUCT_TM_TM_ZONE
 	  // POSIX.1-2024 adds tm.tm_zone which will be used for %Z.
+	  // BSD has had tm_zone since 1987 but as char* so cast away const.
 	  if constexpr (__is_time_point_v<_Tp>)
 	    {
 	      // One of sys_time, utc_time, or local_time.
 	      if constexpr (!is_same_v<typename _Tp::clock, local_t>)
-		__tm.tm_zone = "UTC";
+		__tm.tm_zone = const_cast<char*>("UTC");
 	    }
 	  else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
 	    {
 	      // local-time-format-t is used to provide time zone info for
 	      // one of zoned_time, tai_time, gps_time, or local_time.
 	      if (__t._M_abbrev)
-		__tm.tm_zone = __t._M_abbrev->c_str();
+		__tm.tm_zone = const_cast<char*>(__t._M_abbrev->c_str());
 	    }
 	  else
-	    __tm.tm_zone = "UTC";
+	    __tm.tm_zone = const_cast<char*>("UTC");
 #endif
 
 	  auto __d = _S_days(__t); // Either sys_days or local_days.


More information about the Gcc-cvs mailing list