Year 2038 bug - how big an issue will it be? - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: January 23, 2022, 05:40:58 pm
content: There is one other thread here on this, from 5 years ago.There is just 16 years to go. In the consumer sphere this is ok but in the industrial sphere 16 years is nothing; one expects products to run for longer. I have thousands of products made in say 1995 still installed and running.I am surprised because Y2K was a huge hassle. It wasn't always easy to fix because most RTC designs, including those on micros even today, have just 2 digits for the year, so one had to change the code interfacing to the RTC to interpret the epoch differently. It was harder if the sources were lost or could no longer be recompiled, etc. And most software engineers move on after a few years...A lot of products were scrapped simply because the mfg could not prove Y2K compliance. An amazing waste. Especially as many of them had no RTC or any date-related code at allIt seems that the 2-digit year RTC will not be an issue this time - that's good until 2099. The issue seems to be in the C libraries, which have been only recently fixed, but that will help only with new products. Specifically it seems to be the functions which use milliseconds since 1970 or some such. I've never used these but they seem to be popular for e.g. calculating the number of days between two dates; the intermediate values use a signed int32.

author: Siwastaja
author_rank: Super Contributor
timestamp: January 23, 2022, 05:45:07 pm
content: It's called "unix time" and it's not milliseconds after 1970, but seconds. It's used literally everywhere so it's really surprising you heard about it the first time.In any case, any remotely sensible system and codebase have used 64-bit integer to hold Unix time for a long time; the problem is utterly trivial and known for a long time.But as you can't fix stupidity, certainly some systems will contain such bug. The question is, is this relevant as its own "separate" issue? It's very likely those same contraptions are full of other, even more critical bugs.

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 23, 2022, 06:37:13 pm
content: Still, it'll never cease to amaze me how so many developers make choices based on the "it ought to be enough" paradigm - often collecting the minimum number of other opinions, if any.There are several approaches to picking the "size" of a given object representing some quantity, when the max value is unknown, or could change over time:- Pick the smallest size you can get away with (to save resources), claim the "ought to be enough" method, and move on (by the time it won't be "enough", you'll be long gone...);- Pick a clearly overkill size, so that the limit ever being a problem becomes very unlikely;- Use a variable-length scheme (this one is of course not as trivial to implement, but virtually "unbreakable".)

author: ejeffrey
author_rank: Super Contributor
timestamp: January 23, 2022, 07:29:10 pm
content: Time_t has been 64 bit in the C ABI most of not every 64 bit platform ever made, and later backported to many 32 bit platforms with no native 64 bit type.Probably some 32 bit microcontrollers still use 32 bit time_t since I think you can compile newlib and similar either way and you have a lot more inexperienced people configuring and compiling libc for microcontrollers vs general purpose OSes. Still most systems have it available for years and I would guess that major RTOS platforms will use a 64 bit time_t at least.Having time_t be 64 bit means all the c library functions correctly handle dates past 2038. That doesn't keep programmers from storing timestamps in int, int32 or even long datatypes that are only 32 bit. C doesn't effectively prevent this so undoubtedly some things will break. But software engineering has changed a lot since Y2K. Software is much more likely to be using higher level time/date libraries which handle things properly at least as far as range. I would still expect some issues but nothing extraordinary.

author: TimFox
author_rank: Super Contributor
timestamp: January 23, 2022, 07:41:25 pm
content: There was a short-lived TV animated program about Dilbert, that was often more angry and grim than the daily newspaper comic strip.Back when Y2K was an issue, their treatment of the problem was to show Wally in 1975, when he was still an enthusiastic young engineer just starting at the company. The older employees showed him that they used only two digits to encode the year. He asked, "won't that be a problem in 25 years?", and they laughed at him.

author: gf
author_rank: Super Contributor
timestamp: January 23, 2022, 08:14:40 pm
content: I already see that 2037 may be a good business year for the IT industry, with lots of extra hours - similar to 1999People tend to ignore the problem as long as possible and panic in the last second - shortly befor it is too late.

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 23, 2022, 09:19:58 pm
content: You can literally call this "programmed obsolescence".

author: peter-h
author_rank: Super Contributor
timestamp: January 23, 2022, 09:35:17 pm
content: The Y2K issue (I was very much involved then) was much more to do with the inability of equipment makers to prove Y2K compliance to theirusually much biggercustomers (whose "compliance managers" aggressively demand compliance certification "or else") than the equipment having an actual issue.In the vast majority of cases the equipment didn't even have any kind of date processing. No more than your washing machine has.So this can and will repeat itself just the same.And, after say 10 years, how many companies will be able to find the sources, let alone find somebody who can read them (coders generally hate reading somebody else's code) let alone be able to find somebody who can fix it.In most cases the project won't even compile after say 10 years after it was finished. Or 5 years. Most people know they should archive sources but few know they also need to archive the tools. Maybe create a VM when a project is "finished" and then you can archive the VM - it is only about 10GB. But nobody does this. I had a taste of this with FPGA projects (I used to do FPGA / ASIC design work, using Xilinx FPGAs, and their newer tools could not load older sources. The tools could not be archived either because they were dongledIn the end, even though I had the dongles cracked, I got out of it; it became a completely ridiculous business, if you were running your own company and had to think long term.Project archival is a big issue in many relatively critical areas. For example when Bendix King was taken over and (as usual) trashed by Honeywell, anybody who could write Hello World left to Garmin, and products (e.g. autopilots) finished in say 1999 were completely dead in 2003. The sources "exist" somewhere (I am told by an ex insider) but nobody could touch them.

author: ejeffrey
author_rank: Super Contributor
timestamp: January 23, 2022, 09:52:37 pm
content: Quote from: peter-h on January 23, 2022, 09:35:17 pmThat might be how your were involved but there was a lot more to it than that. And yes some of it was "just" certification but in most cases things that didn't actively process dates could be easily shown to have no issue -- either it has no clock or you can set the clock forward to show it works or you can show a simple work around If your customers were making it harder than that for things that weren't doing scheduling, financial processing, or other work where date / time is directly relevant it was probably just a bit of "me tooism" where they saw a lot of other people working on something and thought they had to participate. That certainly happened but there were a lot of real problems that got fixed and a lot of real certification to validate that systems were ok.

author: peter-h
author_rank: Super Contributor
timestamp: January 24, 2022, 08:37:55 pm
content: I think this will be BIG.For embedded systems, it will be bigger than Y2K whose actual effects were outside the embedded world.And another with GPS, though I would hope currently working units will have coded around it.https://en.wikipedia.org/wiki/GPS_week_number_rollover

author: JohanH
author_rank: Frequent Contributor
timestamp: January 24, 2022, 09:03:45 pm
content: Quote from: Siwastaja on January 23, 2022, 05:45:07 pmEven though it sounds trivial it is a lot of work. It took until kernel version 5.6 (in 2020) until Linux supported 64-bit time_t on 32-bit systems. Even glibc isn't compliant by default (if you’re on a 32-bit system, you have to explicitly build your app with -D_TIME_BITS=64).Lots of old industry systems will have issues (SCADA and the like). There will always be some part of some old system that isn't upgraded to work with this.But it's not the end of the world. Lots of people will work on this and fix things. Critical systems will be tested, replaced and upgraded. Those that won't, probably don't matter that much and can be fixed afterwards if needed.Now, why did Germany announce they will phase out all coal power stations before 2038...

author: ozcar
author_rank: Frequent Contributor
timestamp: January 24, 2022, 10:59:42 pm
content: Quote from: Siwastaja on January 23, 2022, 05:45:07 pmWay back in about 1993 (!), somebody at the place I was working was tasked with contacting all our suppliers in regard to potential y2k issues (yeah might have been a bit ahead of the pack). One of the suppliers responded that they were not aware of any y2k issues, but warned of the looming Unix time issue. I think they did not get the date and time that this would occur quite right, but hey, it is the thought that counts.

author: peter-h
author_rank: Super Contributor
timestamp: January 25, 2022, 07:29:38 am
content: The reason I had not got involved in this is because I never used "seconds since 1970" in anything. I use the unix tm structure (in various code like around the 32F417 RTC) but that doesn't contain such a value.I think the secs since 1970 crops up when using unix library funcs to do date/time calculations and conversions, this value is an intermediate variable.

author: Siwastaja
author_rank: Super Contributor
timestamp: January 25, 2022, 08:07:06 am
content: Quote from: jukk on January 24, 2022, 09:03:45 pmThat's the point. What laymen do not realize when discussing about Y2K & friends, software is full of bugs. Time wraparound related bugs are no special case at all.This happens at much shorter time periods. Boeing 787 must be rebooted every 51 days because some counter wraps around in such short time.Failing to understand the numerical range required and use too small of integer type is one of the most classic types of bugs, and not limited to time.And yes, solution is trivial: just use larger size. It only gets difficult when interchange formats or APIs use wrongly chosen number formats because the real solution is to update the whole API to a new version and then get the developers of all software make updates to use that new version.But it's just software, it's full of bugs anyway, everything can be fixed or worked around. Try to do anything in modern days and our daily life is hindered by massive amounts of software bugs to the point we are so used to it we don't even see it. Rebooting products all the time is the norm. Not being able to call the emergency number without signing in to Microsoft Teams really happened. These are HUGE issues. In 2038, we may see a tiny increase in number of bugs affecting our daily life, but it likely gets lost in noise.

author: peter-h
author_rank: Super Contributor
timestamp: January 25, 2022, 09:48:45 am
content: QuoteAnother report says 284 dayshttps://www.euroga.org/forums/website/3942-a-boeing-787-must-be-rebooted-every-284-daysAs you say, these overflow bugs are everywhere.

author: Siwastaja
author_rank: Super Contributor
timestamp: January 25, 2022, 10:57:37 am
content: I remember hearing even shorter number IIRC. 51 days was the first result found by Googling. Who knows.

author: ozcar
author_rank: Frequent Contributor
timestamp: January 26, 2022, 06:50:04 am
content: Quote from: Siwastaja on January 25, 2022, 08:07:06 amSo many boundary crossings to test and so little time.Years ago the keepers of one particular program were grumpy with us because in their eyes the program had failed because we had changed something in the system it was running on. It turned out that if the memory address of a particular structure was greater than 0x5f5e0ff the program choked.Just the sort of thing you would expect! Well, you might expect it if you knew that somewhere along the way they took a pointer to the structure, converted it into an 8-character decimal string, and then back to a pointer.

author: Ed.Kloonk
author_rank: Super Contributor
timestamp: January 26, 2022, 06:54:02 am
content: Quote from: peter-h on January 25, 2022, 09:48:45 amYou'd just reboot it just before take off, wouldn't ya?

author: TimFox
author_rank: Super Contributor
timestamp: January 26, 2022, 02:40:44 pm
content: Quote from: Ed.Kloonk on January 26, 2022, 06:54:02 amQuite a few years ago, the VP of Engineering and I took a work day trip on a nice clear day from Chicago to White Plains, NY, where the aircraft was a "commuter" jet. We took the first flight on that route early in the morning out of Chicago, returning late afternoon from White Plains. We got to White Plains on time, drove to the site, and returned, where we found the outgoing flight was substantially delayed. Opening up WiFi at the bar, we checked the progress of that aircraft going back and forth, finding that each take-off was increasingly delayed. The VP looked at the data and found that the plane had just started service on the airline, and deduced that the on-board computer had to be rebooted before every takeoff.

author: peter-h
author_rank: Super Contributor
timestamp: January 26, 2022, 05:37:53 pm
content: A reboot before each flight is a standard procedure in some types, especially the smaller commuter jets. It is done to assure a clean config for the avionics.The chances of any passenger jet remaining powered-up for a month or more depends on the operation; it is unlikely.There have been worse things e.g. the navigation crashing when crossing the 180/-180 degree longitude line (not the 0 degree one; that one gets crossed a lot). I've done a fair bit of software in this area and some of the conventions are quite bizzare e.g. heading, or longitude, run from 0 to +179.9999 degrees for the 0-180 half, and 0 to -179.9999 for the 180-359.0000 half. The actual value is represented in ARINC429 using a signed int, typically 20 or 21 bits, IIRC, and you can imagine how careful you have to be handling the transitions from +179.something to -179.something which actually represent a miniscule movement in the heading (or longitude). Same when converting between say a GPS track around North, which NMEA represents as 359.something to 0.something, and as a float (probably a double, to be safe), whereas ARINC429 represents as 0, plus or minus very little. In some cases I had to use signed 64 bit ints so I had extra bits to play with to detect small changes and make them fit properly onto the signed int in ARINC429. So many ways to get bitten. Especially as, due to historical reasons, people writing software in aviation are not the sharpest knives in the drawer.

author: TimFox
author_rank: Super Contributor
timestamp: January 26, 2022, 08:02:48 pm
content: I assume that the apparent re-boots I mentioned were not expected, since they caused a noticeable increasing delay in the back-and-forth operation of the individual aircraft.

author: brucehoult
author_rank: Super Contributor
timestamp: January 27, 2022, 02:52:05 am
content: Quote from: TimFox on January 23, 2022, 07:41:25 pmIn December 1982 at the end of my 2nd year at university I got a summer holiday job at the local city council, computerising their debentures. At various times they had raised funds for works such as improvements to water treatment or building a library by getting 25 or 30 year loans from individuals and institutions such as pension funds. Once or twice a year the accountant would go through all the certificates and make a note of upcoming payments. This was pretty time-consuming.At the time, some loans from the 1950s were still active, and the newest ones would be paid off around 2010. I had to handle dates spanning 2000. The bureau who owned the PR1ME computer on which I would write the loan system (in COBOL) insisted that "for storage reasons" I could only use two digits for the year.I programmed in a modifiable parameter for what year was considered the base year. Initially I made this 1950, so dates from 1950 to 2049 could be represented. I made a menu option to adjust the parameter which, before doing so, checked that there were no still-active loans which were made in the years between the old base year and the new base year.If this system is still in use now, and if new 30 year loans are being raised for capital works, they would have had to adjust the base year parameter for the first time in 2019. If only 25 year loans then they're good for a couple of years yet :-)However I believe this whole system of raising funds for capital investment from the market (including individuals) was banned sometime around 1990 and a government body set up for councils to borrow from.

author: peter-h
author_rank: Super Contributor
timestamp: January 27, 2022, 10:54:57 am
content: Just think... today you can get £1000/day for COBOL66 codingEven more than doing Ruby on RailsI think everybody doing embedded in the later 20th century, using the RTC chips with a 2 digit year (which they still have now!), had to do something like this. You just can't span more than 99 years with it, and preferably cannot go back in time.

author: brucehoult
author_rank: Super Contributor
timestamp: January 27, 2022, 11:32:12 am
content: Quote from: peter-h on January 27, 2022, 10:54:57 amIf I knew where I could do that I'd happily do it. If I can use a modern fast computer, text editor etc to do the dev work with.Well, I wouldn't go to the UK. Remote?QuoteI'm sure it was not at all a unique solution. I was chuffed because it was still 18 years until y2k and the term hadn't been invented ... and I was 19 myself, without experienced programmer supervision.The funniest thing about that summer job was at one point it was the time for people to pay their property taxes ("rates") for the ... quarter (?) ... and a lot of people were still paying in cash. Normally the office girl took the daily cash take to the bank, but for about a week there was several million dollars of cash a day and I was asked (apparently as a strapping lad who might not get mugged?) to carry it to the bank in a suitcase.

author: Ed.Kloonk
author_rank: Super Contributor
timestamp: January 27, 2022, 12:27:10 pm
content: Quote from: brucehoult on January 27, 2022, 11:32:12 am

author: n5al
author_rank: Contributor
timestamp: January 30, 2022, 03:57:26 am
content: Changing the "time_t" parameter from 32 to 64 bits doesn't really solve the year 2038 roll-over problem. It just postpones it for 292 billion years, when we will undoubtedly have to address this issue once again!

author: brucehoult
author_rank: Super Contributor
timestamp: January 30, 2022, 06:03:03 am
content: To be fair, that's 50 times longer than our Sun will exist for.

author: wek
author_rank: Frequent Contributor
timestamp: January 30, 2022, 09:58:25 am
content: Speaking of practical solutions, it would be enough if the existing <time.h> variables/functions would be defined with a user-selectable epoch in mind. Adjusting to different epochs is a trivial typecast/addition/subtraction.Rationale here is, that the vast majority of embedded systems (which is the vast majority of applications using C/<time.h> today) seldom need to look at time before their conception. This (together with rigorous use of uint32_t) would give them >100 years of effective lifetime, together with effective use of 32-bit arithmetics.OTOH, merely increasing time_t to 64-bits in itself may not solve the problem as there may still be arithmetics issues lurking around (seemktime() issue in newlib, but similar may occur in user code, too).Btw. you may also want to look at how year is calculated in current incarnation of newlib's mktime()...JW

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 30, 2022, 05:26:30 pm
content: Quote from: brucehoult on January 30, 2022, 06:03:03 amIndeed.But switch to a 1-µs resolution, and suddenly... =)

author: nctnico
author_rank: Super Contributor
timestamp: January 30, 2022, 06:09:10 pm
content: Quote from: SiliconWizard on January 30, 2022, 05:26:30 pmOr 1 femto second. Yes, that is a real problem for a project I'm working on; not a hypothetical what-if. Having support for 128 bit integers would be great.

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 30, 2022, 06:26:26 pm
content: Quote from: nctnico on January 30, 2022, 06:09:10 pmDunno what language(s) you use, but you can always roll your own. Not too hard.And, as I suggested earlier, if you really don't want to limit the width, you can use arbitrary-precision arithmetic - GNU GMP works really well, and is an option unless the added code size is too much.It's "interesting" to notice that current major C (and so I guess C++) compilers don't seem to support 128-bit integers (at least last time I checked, and at least using the standard types), even the ones that produce 64-bit code (while the ones that produce 32-bit code do support 64-bit integers!) GCC supports it as an extension, but only for targets that have native 128-bit operations: thehttps://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html- whereas, as I just said, "emulated" 64-bit is no problem using (u)int64_t and siblings, on 32-bit targets. Go figure...

author: brucehoult
author_rank: Super Contributor
timestamp: January 30, 2022, 09:40:10 pm
content: Quote from: SiliconWizard on January 30, 2022, 06:26:26 pm"gcc" (which is really Apple LLVM) on my M1 Mac does __int128 ok. No such thing as int128_t though :-(Code:#define big __int128big add(big a, big b){return a + b;}Code:0: 40 00 00 abaddsx0, x2, x04: 61 00 01 baadcsx1, x3, x18: c0 03 5f d6retSo does actual gcc for riscv64:Code:0000000000000000 <add>:0: 87aa mv a5,a02: 9532 add a0,a0,a24: 00f537b3 sltu a5,a0,a58: 95b6 add a1,a1,a3a: 95be add a1,a1,a5c: 8082 retBut it's not supported for riscv32 :-(Of course you can implement it yourself in pure C using the same technique as riscv64 does:Code:#include <stdint.h>struct int128 {uint64_t hi; uint64_t lo;};struct int128 bar(struct int128 a, struct int128 b){struct int128 r;r.lo = a.lo + b.lo;r.hi = a.hi + b.hi + (r.lo < a.lo);return r;}That will work fine on both 32 bit and 64 bit machines, though of course it will make quite a bit of code on a 32 bit machine!On the M1, LLVM doesn't realise it can use the carry flag, but it doesn't matter too much:Code:0000000000000000 ltmp0:0: 61 00 01 ab adds x1, x3, x14: 48 00 00 8b add x8, x2, x08: 00 35 88 9a cinc x0, x8, hsc: c0 03 5f d6 retBut gcc on Ubuntu amd64 realises it can use the carry flag:Code:0000000000000000 <bar>:0: f3 0f 1e fa endbr644: 48 89 d0 mov %rdx,%rax7: 48 01 ce add %rcx,%rsia: 48 89 f2 mov %rsi,%rdxd: 48 11 f8 adc %rdi,%rax10: c3 retqOoooo .. shiny new Control Flow Integrity instruction!

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 31, 2022, 02:32:46 am
content: Quote from: brucehoult on January 30, 2022, 09:40:10 pmYes, as quoted from gcc's docs, __int128/__uint128 is a purely gcc extension (likely supported by LLVM and other compilers) that is only supported on targets that have native 128-bit operations...I suppose this all comes from the fact that the C std still does not *mandate* (but of course allows!) integer widths larger than 64 bits. So while implementations can absolutely define much wider integers, they do not *have* to provide, for instance, int128_t. But why gcc maintainers have chosen not to define int128_t as __int128, I have no clue. It wouldn't be non-conforming to the std as far as I know! Maybe that's just due to the fact that since it's not *mandated* to support it, they chose not to define the equivalent stdint type, in order for users not to expect having it supported on other compilers... maybe. And, the fact they chose not to even define a 128-bit type (even as an extension) for 32-bit targets is a mystery. Just again likely to be rooted in the "ought to be enough" syndrom.As a side note regarding C - a related issue is that, while the std allows stdint's > 64 bits (but allows them of course), it does not define any integer type that could map to a 128 -bit integer - at least if the implementation supports all fixed-widths from 8-bit to 64-bit (which is the usual) - because stdint.h is currently nothing more than implementation-specific macros that map to the standard 'int', 'long int', 'long long int'... but I don't think you can add more 'long' qualifiers to the party (or can you?) Well, this is the part of C that still severely bites. =)

author: brucehoult
author_rank: Super Contributor
timestamp: January 31, 2022, 02:49:10 am
content: Quote from: SiliconWizard on January 31, 2022, 02:32:46 amNONE of the ISAs I showed code for -- amd64, arm64, and riscv64 -- have native 128-bit operations.All of them implement __int128 by doing multiple operations with 64 bit ints.There is absolutely nothing to prevent you implementing __int128 operations using 32 bit operations -- it just takes more of them.Compiling the code I showed (function bar) on any 32 bit platform will do exactly that.Code:#include <stdint.h>struct int128 {uint64_t hi; uint64_t lo;};struct int128 bar(struct int128 a, struct int128 b){struct int128 r;r.lo = a.lo + b.lo;r.hi = a.hi + b.hi + (r.lo < a.lo);return r;}For example, here's the result on arm32 (implementing a 128 bit add using C on a 32 bit machine)Code:00000000 <bar>:0: b082 sub sp, #82: e92d 03f0 stmdb sp!, {r4, r5, r6, r7, r8, r9}6: a906 add r1, sp, #248: e881 000c stmia.w r1, {r2, r3}c: e9dd 2308 ldrd r2, r3, [sp, #32]10: 990c ldr r1, [sp, #48] ; 0x3012: 1854 adds r4, r2, r114: 990d ldr r1, [sp, #52] ; 0x3416: eb43 0501 adc.w r5, r3, r11a: 9906 ldr r1, [sp, #24]1c: 9e0a ldr r6, [sp, #40] ; 0x281e: eb11 0806 adds.w r8, r1, r622: 9e07 ldr r6, [sp, #28]24: 990b ldr r1, [sp, #44] ; 0x2c26: eb46 0901 adc.w r9, r6, r12a: 429d cmp r5, r32c: bf08 it eq2e: 4294 cmpeq r4, r230: bf34 ite cc32: 2301 movcc r3, #134: 2300 movcs r3, #036: eb18 0803 adds.w r8, r8, r33a: f149 0900 adc.w r9, r9, #03e: e9c0 8900 strd r8, r9, 42: e9c0 4502 strd r4, r5, [r0, #8]46: e8bd 03f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9}4a: b002 add sp, #84c: 4770 bx lrOr riscv32...Code:00000000 <bar>:0: 0085ae03 lw t3,8(a1)4: 00c5a303 lw t1,12(a1)8: 00862683 lw a3,8(a2)c: 00c62783 lw a5,12(a2)10: 00de06b3 add a3,t3,a314: 01c6b833 sltu a6,a3,t318: 00f307b3 add a5,t1,a51c: 00f80833 add a6,a6,a520: 0005a883 lw a7,0(a1)24: 0045a703 lw a4,4(a1)28: 00062783 lw a5,0(a2)2c: 00462603 lw a2,4(a2)30: 00f887b3 add a5,a7,a534: 0117b8b3 sltu a7,a5,a738: 00c70733 add a4,a4,a23c: 00e88733 add a4,a7,a440: 00100613 li a2,144: 00000593 li a1,048: 00686863 bltu a6,t1,58 <.L2>4c: 03030863 beq t1,a6,7c <.L4>00000050 <.L3>:50: 00000613 li a2,054: 00000593 li a1,000000058 <.L2>:58: 00c78633 add a2,a5,a25c: 00f637b3 sltu a5,a2,a560: 00b70733 add a4,a4,a164: 00e787b3 add a5,a5,a468: 00c52023 sw a2,0(a0)6c: 00f52223 sw a5,4(a0)70: 00d52423 sw a3,8(a0)74: 01052623 sw a6,12(a0)78: 00008067 ret0000007c <.L4>:7c: fdc6eee3 bltu a3,t3,58 <.L2>80: fd1ff06f j 50 <.L3>This takes a few more arithmetic operations than on a 64 bit machine, but most of the extra code is loading the arguments from RAM and storing the result in RAM as the ABIs don't have any way to pass arguments the size of four registers in registers.

author: Pineapple Dan
author_rank: Contributor
timestamp: January 31, 2022, 09:24:40 pm
content: Quote from: peter-h on January 24, 2022, 08:37:55 pmI have an old Garmin GPS 12 that is affected by this. Didn't know about the rollover problem until one day I switched it on and it told me I was in 1997

author: brucehoult
author_rank: Super Contributor
timestamp: January 31, 2022, 09:35:59 pm
content: Quote from: Pineapple Dan on January 31, 2022, 09:24:40 pmMy first two GPS's have been through two date rollovers now!My oldest I've have since 1994(the big guy on bottom left)

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 31, 2022, 10:16:01 pm
content: Quote from: brucehoult on January 31, 2022, 02:49:10 amOh, I know. I was just deriving the point from gcc's docs (that I linked). Admittedly, the paragraph on 128-bit integers is not crystal clear.So just some guesses here - since I don't know exactly what led to those decisions:- Regarding amd64: strictly speaking you're right, but actual x86_64 processors (Intel, AMD) have had some 128-bit registers for a pretty long time now (through extensions mainly), so my guess it that gcc first added 128-bit integer support for those targets, hence the "explanation" made in the linked paragraph;- Then probably many people using other 64-bit targets (or plain amd64 without extensions) asked for support of 128-bit integers too, and not adding that support for those would have looked like unacceptable bias towards specific targets (albeit very common ones) - so they added this using software emulation;- For the record, as I remember, 128-bit integers were also supported as an extension in MSVC a "long" time ago, so that may have also been part of the trigger regarding x86_64 targets;- For 32-bit targets, as I said, there was probably very little demand in comparison, so they just didn't bother;- Also as I mentioned, since widths > 64 bits are not *required* to be implemented (from the std), there is no incentive for generalizing this implementation for all targets.Again, just guesses here, but the most "reasonable" I can come up with, given the information I have about this.Maybe the real rationale is a bit different and more "political" than this, or due to a number of constraints in the compiler design, I dunno.

author: brucehoult
author_rank: Super Contributor
timestamp: January 31, 2022, 10:27:22 pm
content: Quote from: SiliconWizard on January 31, 2022, 10:16:01 pmWhat registers would those be?If you mean SSE, those are for SIMD, they support parallel operations on data from 8 to 64 bits in size. They don't support 128 bit arithmetic.

author: NiHaoMike
author_rank: Super Contributor
timestamp: February 02, 2022, 02:07:28 am
content: Quote from: TimFox on January 23, 2022, 07:41:25 pmThe game Detroit: Become Human is set in the year 2038 as a similar reference to the problem.

author: Ed.Kloonk
author_rank: Super Contributor
timestamp: February 02, 2022, 02:29:43 am
content: Quote from: NiHaoMike on February 02, 2022, 02:07:28 amLemme guess. Game stops working after 2038?The ultimate Easter egg.

author: Renate
author_rank: Super Contributor
timestamp: February 02, 2022, 07:31:34 pm
content: Some of us just laugh at 2038 bugs. We'll be dead by then.

author: TimFox
author_rank: Super Contributor
timestamp: February 02, 2022, 07:42:53 pm
content: Yes, Wally's senior colleagues in 1975: most of them dead now (47 years later) and the rest no longer interested in industrial software.

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 02, 2022, 08:19:34 pm
content: Quote from: brucehoult on January 31, 2022, 10:27:22 pmYes, the xmm registers. SSE grows in each new generation, so I don't even know what kind of instructions there are in the latest ones, but there sure is a lot of them. While none seems to directly allow basic 128-bit arithmetic such as addition and subtraction of two 128-bit integers, there are of course the logic operations (bitwise) who do. And, I've seen a few instructions that can do some fancy operations on several 8-bit to 64-bit pieces and yield a single result on 128-bit... so, you tell me if that counts as 128-bit arithmetic or not... but if you want to issue a single addition or subtraction of 128-bit numbers, then, right, that's a no. (At least as of yet, and that I know of...)Oh, and 128-bit xmm registers were also available in 32-bit mode IIRC, so...But we're digressing. All I was doing is making some hypothesis (which sounded reasonable, at least to me), based on this point in gcc's docs:QuoteSo, do the x86 xmm registers fit this description? Go figure. Was the x86 the first target getting __int128 support in gcc? That's my take here, but I don't know for sure (and if so, why in 64-bit mode only?). Finally, what does the above sentence really mean? We possibly need a PhD in gcclogy to make full sense of it.But if anyone having been part of the decision process for this can chime in - which is likely to never happen - to explain the real rationale behind the choice of implementing __int128 only on 64-bit targets (and maybe not even all of them, I haven't checked)...

author: brucehoult
author_rank: Super Contributor
timestamp: February 02, 2022, 09:28:39 pm
content: Quote from: SiliconWizard on February 02, 2022, 08:19:34 pmI think that statement is simply wrong and/or outdated rather than needing to be parsed correctly.If the maintainers of avr-gcc decide to implement and commit support for 64 and 128 bit integers on their 8 bit CPU, is someone really going to tell them they can't upstream it because "the docs say we only support __int128 on targets with native support for it"?(AVR can *just*, using every one of its thirty two 8 bit registers, hold two 128 bit integers in registers at the same time. Not very practical. But you could implement a 128 bit accumulator using 16 registers and implement operations between that and RAM. That's still better than making 128 bit arithmetic purely RAM-to-RAM like all other 8 and 16 bit CPUs I can think of need to do)

author: peter-h
author_rank: Super Contributor
timestamp: February 04, 2022, 12:10:55 pm
content: This is getting way off topic but surely a compiler can transparently implement any data type. 128 bit ints are easy. In years past, we even had BCD floats (for accountancy and such).

author: Siwastaja
author_rank: Super Contributor
timestamp: February 04, 2022, 02:19:23 pm
content: Quote from: peter-h on February 04, 2022, 12:10:55 pmOf course it's trivial. The question is why they don't do that. It's not mandated by the C standard, so you could argue that not having optional features forces people write more portable code, i.e., implement any such feature themselves.Yet codebases are actually full of compiler-specific stuff and I'm all for that. Just-In-Time works here: try to make it portable within sensible limits, but don't waste too much time on that, do that only when youactuallyneed to port it. Chances are, the "compiler-specific" feature after all exists on the target compiler, even if it didn't when you started the job. At the end of the day, this tends to lead into standardization of commonly used patterns.I would also like to see types like uint24_t or uint96_t which make sense on 8-bit and 32-bit architectures, respectively. But of course we can't have everything. 128-bit types would be actually useful.And that would actually be one step towards arbitrary length bit array. It's not one or two times I use uint64_t not to represent large numbers, but to represent a 8-byte buffer. I can shift bits in and out, mask bits out of it, and compare the whole buffer with ==, <, >, != and so on. This strategy as it stands only works with 8, 16, 32 and 64-bit buffers. For everything else, you need to write buffer handling code.

author: bson
author_rank: Unknown
timestamp: February 04, 2022, 04:58:24 pm
content: stdint.h is defined by POSIX:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.htmlgcc implements its builtin types using a __ prefix, then stdint.h isn't much more than a set of typedefs to expose them. There is no typedef for int128_t presumably because POSIX hasn't required one. But it does look like it should be permissible to define other types supported by a compiler as long as it follows the same pattern.

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 04, 2022, 07:34:14 pm
content: Don't confuse POSIX with the C standard. Those are two different things. And stdint.h is a C standard thing since C99, that is over two decades ago. The std defines those new "types" without imposing a limit AFAIR. But it just *requires* implementations to support at least up to 64 bits. The rest is up to the implementation. It's certainly not a violation to define int128_t, or even int256_t, or whatever.As to gcc's rationale here, again here nobody knows. I guess some people among gcc maintainers do.There's something from the standard that kind of "promotes" implementing this as extensions though: the std defines the stdint integers through the inclusion of 'stdint.h', the corresponding types (such as intxx_t...) NOT being keywords of the language. So it's quite logical that compilers would either use the std keywords (such as char, short, int, etc...) for defining stdint integers, or use some proprietary extensions. No choice here. Now why they didn't map the __int128 extension to int128_t in stdint.h, that's a bit puzzling. As we said, maybe that was to avoid people thinking using this type would be portable, but no such thing is said in the standard itself.As to 32-bit targets, I guess you gotta draw the line somewhere when it comes to non-mandatory features, and this is likely the main point. Sure they could have implemented 128-bit integers for 32-bit targets. But now some people may ask for 256-bit integers. And so on...And sure it's not hard to hand-implement them anyway, so back to the topic somewhat, not having 128-bit integers (or any other width) supported is certainly no good excuse for not using them if required by some application. Just implementing addition and subtraction (you usually don't need anything else for time stuff?) would take about a couple minutes of development time (if you don't already have that kind of code ready!) - would it be worth saving a few minutes of dev time and end up with an application that would just be a time bomb?But anyway - as always, this kind of limitations in software mostly comes from 3 things IMO: laziness from developers (that happens), lack of foresight (happens a lot too), or planned obsolescence (adding limits in software is an excellent way of forcing users to upgrade.)

author: Siwastaja
author_rank: Super Contributor
timestamp: February 05, 2022, 11:44:07 am
content: IMHO, they just define int128_t in stdint.h.It might cause a few unhappy campers with a small portability surprise, but as a whole, it would drive the C language in good direction. And I'm sure other compilers would follow. Except those who never follow, or even support stadard C99.

author: bson
author_rank: Unknown
timestamp: February 05, 2022, 08:25:25 pm
content: Quote from: SiliconWizard on February 04, 2022, 07:34:14 pmYeah, but the POSIX standard is more recent and has some useful additions, like ptrdiff_t.