6 ms·
Tips for stable and portable software
- kasperni 6y ago> Tips for stable and portable software I think a more accurate title would be "Tips for stable and portable C programs"
- Cthulhu_ 6y agoThe author lists a number of languages considered stable, C being one of them because of widespread support and portability. Java isn't portable for example because it depends on the JVM (and I know GraalVM is a thing but will you still be able to use it in ten years?).
- brabel 6y agoThe argument against Java is weak... You can take the latest JVM and run any jar from 1999. Also, Java has had jlink in the latest versions which compiles a runtime that does not require a JVM installation, you don't need GraalVM for that.
- kasperni 6y agoShow me a JavaScript developer that cares deeply about POSIX or the operating system they are running on. And what about Windows? It is still used on 80% on all computers? So why is POSIX essential?
- Shared404 6y agoHaven't done much work with servers I take it. Almost any OS running on a server is going to be POSIX, probably Linux or BSD.
- nicoburns 6y ago> Java isn't portable for example because it depends on the JVM By that logic C isn't portable because it relies on libc.
- AtlasBarfed 6y agoThe JVM has multiple implementations across a huge range of architectures. Java is managed by a standards process. Once excluded, the article goes into depth on a range of things that one could argue Java specifically addresses and in a better, more portable way. One could argue about GUIs, but the portability of GUIs is not just a Java/Swing problem.
- deleted 6y ago[deleted]
- chrisco255 6y agoFrom the title, I was hoping to hear about software systems that have powered infrastructure for decades, but unfortunately it was more of a programming language analysis strategy.
- deleted 6y ago[deleted]
- fjfaase 6y agoOne day, maybe when I am retired, I am going to develop a programming language-agnostic algorithm specifying language with which you can generate code for programming languages ;-). A kind om Mathematica, but than for software.
- throwaway_pdp09 6y agoMany compilers target C, that seems like a decent approach - any problem with that?
- fsloth 6y agoLike this? https://github.com/imatix/gsl https://github.com/imatix/gsl
- MaxBarraclough 6y ago> programming language-agnostic algorithm specifying language with which you can generate code for programming languages That's just a programming language tailored for transpilation, no? Theoretical computer science shows us there is no 'one true representation' for algorithms.
- fjfaase 6y agoI have to admit that I was little joking about this. But I do think it is possible to specify an implementation of how a complex operation can be achieve by combining more primitive operations. With digital computers, data is usually represented by certain representation of bits. An operation is usually defined on these kind of representation. Think for example of an operation for adding two numbers in a certain representation, resulting in a result with a certain representation. In computers, two most primitive adding operations are usually adding modulo some power of 2. But with these, we can implement adding for much large numbers (also using other kinds of operations and/or intermediate storage).
- AnIdiotOnTheNet 6y agoYou're basically describing a virtual machine. Compile to bytecode and the runtime JITs (or AOTs) it on the host. It is an idea decades old.
- deleted 6y ago[deleted]
- ut6Ootho 6y agoThis article certainly rings a bell, as I started rewriting my personal projects to C in the last year, precisely because I wanted to make them decades-proof. I still use the same vimscripts I wrote in early 2000', I want the same thing for all my tooling and apps. I'm not sure it makes sense professionally, though, as most codebase won't survive a decade : after three years, the dev team will turn over, and the new team will want to rewrite everything from scratch. Or start rewriting parts of the exisiting system in a new language, until it ultimately eat it up. It may be related to the kind of companies I work with, though (very early stage startups). Regarding interfaces, I think the author could have gone a step further. There is actually a standard and portable interface system: html/js/css. If you write a dependency free web app using things like webcomponents and other standard techs, you know it will stand time, and it actually matches all the reason why the author want to use C : standard and multiple implementations.
- user5994461 6y agoIt's highly dependent on the domain. If you're in a web startup, software won't last 3 years, the next team will systematically rewrite. If you're in the bank, logistics, defense sector, it's very likely the software will go for a decade, as long as it's not killed the first or second year for being a pet project (initial manager left) and having no customer.
- RandoHolmes 6y ago> If you're in a web startup, software won't last 3 years, the next team will systematically rewrite. I have an old man rant about that actually... that rewrite is typically unnecessary if you actually use discipline when developing and learn how to read code. I once took on a CakePHP 2 app and another developer asked me how in the world I got into, and understood, the framework so quickly. My secret? I read the CakePHP 2 source code. So many developers learn how to do that very well.
- phone8675309 6y ago> that rewrite is typically unnecessary if you actually use discipline when developing and learn how to read code "But developers that can exercise discipline and know how to read (and modify) code instead of rewriting cost so much money..." is what you'll typically hear in response to this. It's cheaper (and often faster) to have cheaper, less disciplined, less experienced developers rewrite something multiple times than it is to have more expensive, more disciplined, more experienced developers write something and maintain it. It's also harder to keep the more experience developers because most developers I work with start looking for another job when their project goes into maintenance. The typical "we never have enough time/money to do it right the first time but we always have to make the time/money to do it twice" situation.
- CJefferson 6y agoI've currently involved with a system, written in C, which has been going for 30 years: GAP - https://www.gap-system.org https://www.gap-system.org While I write a lot of C, I immediately disagree with the idea that C has a "simple (yet expressive) abstract machine model". Every so often we find a bug which has been present for over a decade, because some new compiler has added a (perfectly legal by the standard) optimisation which breaks some old code. Picking one example: in the "old days", it was very common (and important for efficiency) to freely cast memory between char, int, double, etc. For many years this was fine, then all compilers started keeping better track of aliasing and lots of old code broke. Also, while POSIX is a nice base, it stops you using Windows, and also almost every non-trivial program ends up with a bunch of autoconf (which has to be updated every so often) to handle differences between linux/BSD/Mac. Also, definatly don't distribute code where you use flags like '-pedantic', as it can lead to your code breaking on future compilers which tighten up the rules.
- pwdisswordfish4 6y ago-pedantic only enables warnings, it cannot change the meaning of code; not even on newer compilers.
- OnlyOneCannolo 6y agoRight, but that's not the concern. You compile your code with -pedantic, it works, and then you distribute the source. A user gets that code, compiles it, it works, and they integrate it into their product. Later, that user upgrades or changes their compiler and your code doesn't build anymore because there's a new warning. Now they have to patch your build.
- CJefferson 6y agoYou are right, I mis-remembered what the flag did, sorry. I've seen projects with -pedantics -Werror, which are particularly annoying (-Werror in general to be honest, I understand why people might want it for CI of course).
- 6y ago
- divan 6y agoObligatory mention of Ten Years Reproducibility Challenge https://github.com/ReScience/ten-years https://github.com/ReScience/ten-years
- jart 6y agoThat forceinline definition is just tip of the iceberg. It's so hard to define in a way that works with different versions of GCC, -Werror, instrumentation, MSVC, and profiling. If you care about portability, consider just not caring and using static. Too much special casing code can actually make it harder for people in weird environments to use your code, since something is going to break it, and reading past the ifdef soup becomes the biggest obstacle.
- Cthulhu_ 6y agoI'm currently "betting" on Go for making a back-end (just a REST API + sqlite database) that will last a decade; I'm betting on the tooling to stay backwards compatible or with minimal changes in the codebase; I'm betting on the readability of my own code for the next decade, and I'm betting on the language + tools to continue to be developed whilst sticking to their original goals. Generics is going to be fun.
- RandoHolmes 6y ago> I'm betting on the tooling to stay backwards compatible or with minimal changes in the codebase This is actually why I'm pretty bullish on things like RoR, Laravel, et al. The sheer speed at which they go to a new version that breaks BC is actively making the web less secure. I've lost count of how many times I've found a new client with this software that's been working for years but suddenly broke, only to realize it's on an OS that's EOL, using a version of the framework that's EOL and a version of the language that's EOL. And now it's my job to bring it up to speed. And typically the hardest part of that? The 3rd party dependencies that are either abandoned and don't support the newer versions of anything, or have moved onto Python 3 and no longer support Python 2. It's why I vastly prefer something like asp.net core. I know in 5-10 years the code will probably just work with the latest version, and if there's an incompatibility, it's going to tend to be relatively small.
- vbsteven 6y agoThe same reason why my default stack is still Java/Kotlin with Spring and Hibernate. A stable environment, stable runtime that is guaranteed to not change too much and has a culture of backwards compatibility.
- gonzo41 6y agoHow are you liking Java with all the versions that are dropping. Are you still on 8? Correto? Or are you keeping up? and do you see the value in the features that are dropping.
- jankotek 6y agoHm, decades is not that much, most enterprise code fits into that. But how about 200 years? It is about people. Documentation, paper trail why some decisions were made, archiving build tools, VMs, dependency source code.. Also C, POSIX and Motif are terrible choice for their fragmentation. Java is very booring, but compiling and debugging 20 years old code is very common.
- iso8859-1 6y agoReally weird that he recommends Motif. Motif is not comparable to Web/Gtk/Qt since it has only the most primitive widgets, and no 3D support. I would propose doing a web-app if you really care so much about compatibility. Web also allows for more custom widgets.
- MaxBarraclough 6y ago> I would propose doing a web-app if you really care so much about compatibility. Still better watch your step. Features can be removed from the platform. https://stackoverflow.com/a/46689336/ https://stackoverflow.com/a/46689336/
- rjsw 6y agoWhat widgets do you feel are missing from Motif ? And why would it need 3D support ?
- jmnicolas 6y agoSo now you have to support all browsers : Firefox, Safari, Chrome and Edge. Plus some old stuff because this customer still has a Centos 4 Workstation running and another has a few Windows XP PCs that are mission critical. I don't know if Motif is better at that, but I wouldn't bet on web-apps personally.
- timw4mail 6y agoIs Motif actually available on modern Linux systems? And is there a Windows port as well? I find it difficult to believe that Motif is actually that portable. Web apps are only as portable as the browser features they use, and the browsers available for the platform. A primarily backend-rendered app, with minimal Javascript is much more portable than the average SPA app.
- yjftsjthsd-h 6y ago> Is Motif actually available on modern Linux systems? https://www.archlinux.org/packages/community/x86_64/openmotif/ https://www.archlinux.org/packages/community/x86_64/openmoti... lists as being updated 2020-01-05, and https://sourceforge.net/p/cdesktopenv/wiki/SupportedPlatforms/ https://sourceforge.net/p/cdesktopenv/wiki/SupportedPlatform... claims that CDE supports a rather lot of platforms (which implies motif), although I'll grant that most of those probably haven't been tested in a while.
- MaxBarraclough 6y agoSeems like good advice. I'd add another one that seems completely obvious, but some sloppy developers ignore it: avoid undefined behaviour. If you're going to work with C, you need to know about undefined behaviour and take it seriously.
- rini17 6y agoIf it were so easy, there would be already specified a subset of C without undefined behavior and you could be able to automatically check your code against it.
- gonzo41 6y agoYou could follow NASA standards. They've got a pretty good record with c. But it'll cost you.
- MaxBarraclough 6y agoLink: https://web.archive.org/web/20190213011655/http://homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf https://web.archive.org/web/20190213011655/http://homepages.... Alternatively, NASA host an uglier scan of the document at https://ntrs.nasa.gov/citations/19950022400 https://ntrs.nasa.gov/citations/19950022400
- MaxBarraclough 6y agoMy point was only that C programmers should be keenly aware of the pitfalls of undefined behaviour, rather than blithely ignoring it. I've been surprised by the sloppiness of some developers on this point. > a subset of C without undefined behavior There are various projects out there that let you produce C code guaranteed to be free of undefined behaviour, but they're not 'quick fix' solutions, so they're not widely used. https://www.eschertech.com/products/ https://www.eschertech.com/products/ https://github.com/zetzit/zz https://github.com/zetzit/zz https://blog.regehr.org/archives/1069 https://blog.regehr.org/archives/1069 (ctrl-f for actually)
- 6y ago
- ludocode 6y agoThis is mostly good advice. I don't love configure scripts, I don't agree with the heavy reliance on POSIX if you intend to be compatible with Windows, and I don't love the fact that the author recommends third party data structure libraries that they haven't actually used. For container libraries in C, you really have to use them to get a feel for their usability (this sounds like a tautology but it's not.) I disagree strongly with one recommendation. This is just an example, but it holds for larger API design in general: > we could add a fallback to reading /dev/random. [...] However, in this case, the increased portability would require a change in interface. Since fopen() or fread() on /dev/random could fail, our function would need to return bool. No, definitely not. It is dangerous to expect the application to sanely handle the case of randomness being unavailable when it is never going to occur in practice. On all POSIX platforms, /dev/random exists and will block until sufficient entropy is available. Something would have to go seriously wrong for this to fail. This is so rare that any error handling code for it will never be tested. The most likely outcome of forcing the caller to handle it is that the return value is ignored or improperly handled and the buffer is used uninitialized, leading to a security vulnerability. My recommendation instead would be to error check your fopen() and fread() calls within get_random_bytes(), and print an error and abort() if they fail. This way if someone's system is improperly configured and /dev/random doesn't work the program will just crash. Same goes for macOS's SecRandomCopyBytes() and Windows' half a dozen calls to use an HCRYPTPROV. This way you still return void and there is no danger of callers improperly handling errors. In general, unless you're writing safety-critical software, it's fine for your code (or even library code) to abort() in these sorts of exceptional situations when there is no reasonable or safe way to handle the error. If someone truly wants to handle the error, they can just not use your API and do it manually.