8 ms·
JPL Institutional Coding Standard for the C Programming Language (2009) [pdf]
- ZachWick 8y agoIn previous embedded work, I've had to follow the MISRA C [0] guidelines, which I suspect are roughly similar to the JPL guidelines (but I can't get to the PDF at the moment due to the bad SSL cert). [0] https://en.wikipedia.org/wiki/MISRA_C https://en.wikipedia.org/wiki/MISRA_C
- guitarbill 8y ago> Two earlier efforts have most influenced the contents of this standard. The first is the MISRA-C coding guideline from 2004 [...] Not just similar, but based on MISRA C! MISRA C can be a total PITA though (I get why, but it doesn't make it any less annoying). Some well known storage products follow similar principles without being quite so stringent. It's quite a nice middle ground, and - if you are, err, detail oriented - can be a less aggravating experience than sloppy, higher level codebases (yes, Java, I'm looking at you mainly).
- carlmr 8y agoMISRA C is annoying mostly if you have to change the codebase to fit the standard. If you iteratively solve MISRA warnings they become second nature and you almost don't make them anymore. What is annoying is the paperwork when you need a deviation. However that's kind of the point of the process. Make it annoying enough that people really think about whether the deviation is necessary. At the same time it's only a coding standard. Not a panacea for all your coding issues. You can have 100% MISRA conformant spaghetti. It does reduce the "shoot yourself in the foot" surface area a little bit though.
- acprog42 8y ago> You can have 100% MISRA conformant spaghetti. IMHO some of MISRA rules lead directly to hard to read/maintain code. Consider a function that: 1. opens a file 2. allocates enough memory to store the whole file 3. reads the file 4. return the allocated buffer on success or NULL on failure You want to write it so it doesn't leak either memory or file handles whether successful or not (if successful ownership of the memory buffer is passed to the caller so it must not be freed in that case). To be MISRA compliant you'd either end up with a "Christmas tree" of nested scopes or if-statements with extra && in them (pseudo C-code): char *buf = NULL; FILE *fh = fopen(...); if (fh) { if (success(fseek(fh, end))) { long int sz = ftell(fh); if (sz > 0) { buf = malloc(sz); if (buf) { if (failed(fread(fh, buf))) { report_error(); free(buf); buf = NULL; } } else { report_error(); } } else { report_error(); } } else { report_error(); } fclose(fh); } else { report_error(); } return buf; However if you were allowed to use goto with a single exit-label the code would be much cleaner and easier to follow: char *buf = NULL; char *rv = NULL; FILE *fh = fopen(...); if (!fh) { report_error(); goto exit; } if (fail(fseek(fh, end))) { report_error(); goto exit; } long int sz = ftell(fh); if (sz <= 0) { report_error(); goto exit; } buf = malloc(sz); if (!buf) { report_error(); goto exit; } if (failed(fread(fh, buf))) { report_error(); goto exit; } rv = buf; buf = NULL; exit: if (fh) { fclose(fh); } if (buf) { free(buf); } return rv;
- acprog42 8y agoToo little karma to edit and fix indentation. Anyway given the above functions, think about adding support for only returning the buffer if the file contains a specific word. While certainly doable in both cases I would at least feel more uncertain editing the first without accidentally creating a bug...
- regularfry 8y agoIf you allowed yourself a second label, you could clean up those repeated `report_error()` calls, too.
- acprog42 8y agoTrue, it would be kind of analogue to try/except/finally if you do that.
- Jedi72 8y agoI'm so glad I don't use C hahaha. Y'all are crazy!
- carlmr 8y agoI completely agree. Most Misra software is embedded without dynamic allocation though, so you usually don't get into this situation too often. I think an exception here makes sense
- acprog42 8y ago> Most Misra software is embedded without dynamic allocation though True, but I've seen enough MISRA code bases plagued with the "Christmas tree" layout even if dynamic memory allocation isn't allowed. This was just a generic example most people can relate to.
- carlmr 8y agoI just checked, and MISRA 2012 seems to allow goto again under certain preconditions (you have to have a label declared in the same function and it has to be in the same block). So actually you can do proper error handling again. Still single return statement, which usually makes for more spaghetti.
- philpem 8y agoDefinitely agree here. Shoehorning an existing codebase into being MISRA compliant is utter hell. It's something you really need to design-in from the beginning. Also for anyone in the audience who's going "ugh, MISRA..." -- the 2012 spec revision is a significant improvement on the 2004 version and cleans up a lot of the more troublesome rules. Even if I'm not doing MISRA-required code, I still find myself sticking to its suggestions... "Allocate memory statically" is a really good one, especially on embedded systems.
- laveur 8y agoApparently the SSL cert for this got revoked... I wonder if anyone at nasa knows...
- Alupis 8y agoLooks valid on my machine (win10, chrome)
- cbsks 8y agoSafari on iOS does not trust the certificate
- segfaultbuserr 8y agoBecause OCSP is not reliable. Yeah, SSL/TLS is still broken at large, can you believe it, by default, there is NO reliable way to revoke a certificate... If OCSP times out, it just times out, the browser simply ignores it and loads the page without warnings. Active attackers can just block the OCSP server before they can use a revoked certificate with leaked private key to launch a MITM attack. This is why we need OCSP pinning and OCSP Must Staple. OCSP pinning makes the web server itself to delegate OCSP responses in-band, thus eliminates the need for clients to make an unreliable connection to a 3rd-party, improves both security and performance. OCSP Must Staple is a certificate attribute that forces the browser to enforce pinned OCSP checkings. This is also the reason that Let's Encrypt limits the certificate lifetime to 90 days.
- MastrChefRocks 8y ago
- AnimalMuppet 8y ago(2009)
- Alupis 8y agoThere does not appear to be a newer version. Not sure if adding the date here is all that relevant... Not like C programming changes that much these days.
- jvanderbot 8y agoMars rovers don't iterate quickly. This was very much my experience when working on those teams.
- entity345 8y agoDo you think sound C coding practices have changed since?
- AnimalMuppet 8y ago1. It's normal HN practice to give articles a year, if they aren't from the current year. 2. philpem (in https://news.ycombinator.com/item?id=19191721 https://news.ycombinator.com/item?id=19191721) points out that there's a 2012 version of MISRA. I don't know whether there's a JPL update based on that, though.
- entity345 8y agoDo you think sound C coding practices have changed since?
- AnimalMuppet 8y agoDo you think your question is relevant? Certain standards for sound C coding practices have changed since.
- 8y ago
- AnimalMuppet 8y agoRun through a state-of-the-art static analysis tool with no warnings? That's seriously stringent. And then, rule 23: "All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if or #ifdef directive to which they are related." It never even occurred to me that anyone might do otherwise, but yeah, that's a real good thing to forbid. (I once failed to close a C-style comment at the end of an include file. It was the last include file, so the next couple of lines in the C file were commented out - which happened to be the main() function name and the opening curly brace. It then treated the rest of main() as file-level variable declarations, which was fine until we got to the actual code. I got 1800 compiler errors from that...)
- as-j 8y agoYou know rule 23 exists for a reason, someone thought it would be a good idea.....egads, I wonder what evil horrible thing they did.
- cpeterso 8y agoA CppCon 2014 presentation about safety-critical C/C++ coding standards for a different "J" acronym: the Joint Strike Fighter (JSF). "Using C++ on Mission and Safety Critical Platforms". https://www.youtube.com/watch?v=sRe77Mdna0Y https://www.youtube.com/watch?v=sRe77Mdna0Y
- metaphor 8y agoThanks for sharing. Although it isn't my application domain, their considerations were nevertheless interesting. On a general note, this bullet under "Lessons Learned" circa 48:00 hits home: > A rationale for each rule educates developers and gets their buy-in It's been my experience that standards which embody this philosophy are the most pleasurable to work with. On the flip side, I've dealt with "updated" standards which have directly perpetuated technical debt as a consequence of rules defined to address temporal issues that were relevant at the time but passed over in subsequent revisions due to lost tribal knowledge...it's always a challenge addressing this class of rule, even if just trying explain to a new developer on the team without making that person feel like a complete tool.
- xvilka 8y agoBest advice - not to use C wherever possible. There are better languages for many areas. Speaking from my decade of experience as C programmer.
- saagarjha 8y agoThese rules are generally for places where the use of C is unavoidable.
- kobiguru 8y agoIf you are dealing with networking and embedded systems I think C is a must.
- jakeinspace 8y agoPretty much unavoidable when it comes to real time embedded systems. Your options in that world are pretty limited, especially on space-rated processors which are generally many generations old, and can't necessarily handle huge performance overheads.
- froh 8y agoI seriously wonder why Ada didn't catch on more?
- burfog 8y agoThe compilers were expensive. This is probably because Ada was mandated for government projects. The people buying compilers were most likely able to charge that expense to the government, possibly even with a mark-up. The language had a weird temporary resurgence a few years back. It seems to have started by the free Ada compilers becoming decent and by people starting to get serious about security holes. It seems to have ended due to rust claiming that niche.
- pjmlp 8y ago
- saagarjha 8y ago> All C code shall conform to the ISO/IEC 9899-1999(E) standard for the C programming language, with no reliance on undefined or unspecified behavior. Easier said than done ;)
- pjmlp 8y agoIn those environments use of static analysers is enforced, which kind of helps.
- dima55 8y agoNot an "institutional coding standard" by any means. Maybe some groups conform to this, but I haven't come across any.
- jvanderbot 8y agoNot all code complies. But not all code flies. My experience has been that as a mission system passes gates in the years before launch, they asymptotically approach these standards, with exceptions approved by named individuals and reviewed. I doubt many institutional products or teams conform strictly on all projects. That'd be quite unproductive.
- dima55 8y agoNot all code is flight code :)
- arthurcolle 8y agoContent unavailable. Anyone have a decent mirror?
- guitarbill 8y agoJust `curl` it, or use something that allows you to ignore certs.
- arthurcolle 8y agoThanks guitarbill
- enriquto 8y agoThis is a beautiful document and a very sound set of rules.
- okl 8y agoCoding standards can be a pain, but most rules make sense and if they don't make your code difficult to read and unwieldy you should probably create an exception. One example where such an exception would have been justified is found in cFE: https://github.com/nasa/cFE/blob/04c0cc342415575f855dc00960afc8daedd8a46e/cfe/fsw/cfe-core/unit-test/evs_UT.c#L106 https://github.com/nasa/cFE/blob/04c0cc342415575f855dc00960a... Thousands of lines of clutter in the unit tests because they are not using a function-like macro.
- uasm 8y ago> "Do not use goto, setjmp or longjmp." Error handling in C without those primitives will almost always result in horrible code. They should've made an exception here: "goto error;" should've been allowed and encouraged.
- coldtea 8y ago>Error handling in C without those primitives will almost always result in horrible code They don't care for nice code. They care for easily statically checked and verified code.
- philpem 8y agoAs I said else-thread, there's actually a variation in MISRA-C-2012 (or possibly one of the addenda) for this. Error handling using 'goto' is allowed, as long as you're jumping forward (i.e. to or near the end of the function). You can't go backwards through the code. It may require a variation in the project's coding spec but it's certainly possible (because I've been there and done it!)
- nwmcsween 8y agogoto is fine but anything that uses setjmp or longjmp for error handling is absolute garbage code
- GnarfGnarf 8y agoAll in all, sound advice. No recursion? That's a deal breaker.
- lasagnaphil 8y agoNo recursion kinda makes sense, because you really don't want to have an accidental stack overflow while the airplane is off the ground... Interestingly, one of the goals of the Zig language (marketed as a replacement for C, currently in development), is to eliminate stack overflow while keeping recursion (by enabling the user to allocate stack frames in the heap). https://github.com/ziglang/zig/issues/1639 https://github.com/ziglang/zig/issues/1639
- biesnecker 8y agoWouldn't that eventually just lead to an OOM? Most of the time the recursion I write is either well-formed and lives nicely in the stack or poorly-formed and would consume all the memory in the universe if given the opportunity.
- CDSlice 8y agoI don't know very much about C, but it looks to me that no_std Rust with a custom allocator could let you fulfill most of these requirements and keep most of Rust's nice features like Result for error handling. I wonder if JPL/NASA will consider using Rust for any of their future missions.
- deleted 8y ago[deleted]
- 0815test 8y ago> I wonder if JPL/NASA will consider using Rust for any of their future missions. You are quite welcome to try, but don't expect any help - the Rust Evangelism Strike Force is way too busy focusing on world domination on Earth for Rust, at the moment. Missions in outer space are still outside their remit.
- steveklabnik 8y agoWe had a talk at RustConf this year about Rust in space...
- CDSlice 8y agoWas it recorded? That sounds pretty interesting and I would like to watch it.
- steveklabnik 8y agohttps://m.youtube.com/watch?v=Vq03Ba7W95I https://m.youtube.com/watch?v=Vq03Ba7W95I
- kensai 8y agoFound a working PDF link also here: http://everyspec.com/NASA/NASA-JPL/JPL-D-60411_VER-1_32832/ http://everyspec.com/NASA/NASA-JPL/JPL-D-60411_VER-1_32832/