JSF‑AV C++ Coding Standards (2005) - Pocket Cheat Sheet
C++ CODING STANDARDS - FOR THE SYSTEM DEVELOPMENT AND DEMONSTRATION PROGRAM
What this is
A concise, practical summary of the Joint Strike Fighter Air Vehicle C++ Coding Standards (Doc. No. 2RDU00001 Rev C, December 2005). The document’s goal is safe, reliable, testable, and maintainable C++ in a safety‑critical environment; it carries Distribution Statement A (“Approved for public release; distribution is unlimited”).
Scope & how to read the rules
The standard uses three keywords:
shall = mandatory and must be verified
will = mandatory intent, but not necessarily verified by tooling
should = strong recommendation
Breaking a should requires software‑engineering lead approval; breaking a shall/will also needs product‑manager approval, and every deviation from a shall must be documented in the file that contains it.
Big‑ticket rules to remember
Keep functions small & simple. ≤ 200 logical SLOC per function and cyclomatic complexity ≤ 20 (heavy
switchmay exceed). No self‑modifying code.Use ISO C++ (circa 2003). No compiler extensions; stick to the standard.
Restrict the preprocessor. Only
#ifndef/#define/#endif/#include; no macros for constants or inline code—useconst,enum, andinlineinstead.Headers & includes. Use include‑guards; include only headers; prefer
#include <filename.h>(even for project headers) and minimize header dependencies via forward declarations.Style & naming.
Words are
snake_casewith underscores.Classes/structs/enums/typedefs:
Title_case(first letter capitalized).Functions/variables: lowercase.
Constants/enumerators: lowercase.
Acronyms in any identifier stay UPPERCASE.
Classes & OO. Prefer private data (no public data in classes), complete‑yet‑minimal interfaces, declare unneeded compiler‑generated members as deleted/disabled, mark non‑mutating methods
const, and give any base with virtuals a virtual destructor.Inheritance. Use public inheritance for is‑a; model has‑a via composition or non‑public inheritance; keep multiple inheritance to “n interfaces + m private impl + at most one protected impl”. Conform to Liskov Substitution. Don’t redefine non‑virtuals; don’t change default args on virtuals.
Templates. Review and test every actual instantiation produced by your build; document constraints on template parameters.
Functions. No var‑args; aim for one exit (allow extra exits when clearer but clean up resources everywhere); always test error returns. Pass small concrete types by value; otherwise use references (no
NULL) or pointers (whenNULLis meaningful).Control flow. Always brace
if/else/while/for; avoidgoto,continue(and mostbreakoutsideswitch); ensureswitchcasesbreak; have adefaultwhen not exhausting all enum values.Types. Do not use
int/short/long/float/doubledirectly—use fixed‑width typedefs (int32,uint16,float64, etc.) from a project “UniversalTypes” header.Pointers & arithmetic. No pointer arithmetic in interfaces; avoid it generally (use containers/iterators). No more than two levels of indirection. Don’t mix signed/unsigned in arithmetic or comparisons; avoid unsigned arithmetic altogether.
Memory & exceptions. No dynamic allocation after initialization; prefer RAII for resources. C++ exceptions are disallowed (
try/throw/catch).Standard libraries. In safety‑critical code, use only DO‑178B Level A–certifiable runtimes; several C library features are prohibited (e.g.,
stdio,setjmp/longjmp,signal, manytime.hfunctions,atoi/atof/atolunless tightly controlled).Namespaces. Put every non‑local name (except
main) in a namespace; avoid deep nesting (>2 levels).Testing in hierarchies. All base‑class tests must apply to derived classes; for virtuals, cover every dynamic dispatch target (“flattened” coverage).
Quick “Do / Don’t” list
Do
Use
#ifndef/#define/#endifinclude guards; one class per header; forward‑declare where you only need pointers/refs.Inline only trivial (1–2 line) accessors/forwarders.
Prefer
const,enum, andstatic(where applicable) over macros.Brace everything; each statement on its own line; keep lines ≤ 120 chars.
Use
const_cast/static_cast/reinterpret_cast(not C‑style casts), and avoid casting wherever possible.
Don’t
Don’t call virtuals from constructors/destructors; don’t use an object before its lifetime begins or after it ends.
Don’t use recursion (except with strong justification); don’t use
goto/continue; don’t depend on unspecified order of evaluation.Don’t treat arrays polymorphically; don’t pass raw arrays in interfaces—use an
Array/container abstraction.Don’t modify string literals; don’t overload
||,&&, or unary&.
Minimal project setup (how to use this standard)
Create a universal types header (e.g.,
UniversalTypes.h) definingint32,uint16,float64, etc.—then ban rawint/long/doublein code reviews.Turn warnings up and treat them as errors; enable static analysis matching these rules (Appendix B mentions LDRA compliance mapping).
Adopt the file layout & include discipline below; add a pre‑commit check for include‑guard format and
#includepolicy.Enforce complexity and size gates in CI (
≤200L‑SLOC /≤20complexity).Write tests per hierarchy: all base‑class tests must pass on derived classes; add coverage checks for each virtual dispatch path.
Document every deviation from a shall in the source file itself (top comment block), with the two approvals recorded in your CM tool.
Header & source skeletons (JSF‑AV‑compliant)
// telemetry_frame.h
#ifndef telemetry_frame_h
#define telemetry_frame_h
// File: telemetry_frame.h — Air Vehicle C++ interface (JSF-AV style)
// Deviations from *shall* rules: none
#include <UniversalTypes.h> // Fixed-width types (e.g., int32, uint16) // AV 209
namespace avionics { // AV 98
class Telemetry_frame { // AV 50
public: // AV 57
explicit Telemetry_frame(uint16 length); // AV 73, 74
uint16 length() const; // AV 69, 122
private:
uint16 length_;
};
} // namespace avionics
#endif // telemetry_frame_h
// telemetry_frame.cpp
#include <telemetry_frame.h> // AV 33
namespace avionics {
Telemetry_frame::Telemetry_frame(uint16 length)
: length_(length) {} // AV 74, 75
uint16 Telemetry_frame::length() const { return length_; } // inline-worthy (≤2 stmts) AV 121, 122
} // namespace avionics
Notes illustrated: include‑guards and angle‑bracket includes; fixed‑width types; namespaces; constructor member‑init list; trivial accessor inlineable; public/protected/private order; explicit to prevent unintended conversions.
Micro‑references (why these choices)
Preprocessor policy & include‑guards: only the four directives; guards on every header;
#includeonly headers.Naming: classes/enums/typedefs
Title_case; functions/vars lowercase; constants/enumerators lowercase; acronyms uppercase within identifiers.Exceptions & memory: no C++ exceptions; no heap alloc/free after init (avoid fragmentation; use RAII/pools).
One‑page checklist (copy into your repo)
Functions ≤ 200 L‑SLOC; complexity ≤ 20; no recursion.
Include‑guards present; headers include only what they need; forward declare where possible.
No macros for constants; no function‑like macros; constants via
const/enum.UniversalTypes.hused; no rawint/long/float/double.Namespaces used; naming follows JSF‑AV style.
No pointer arithmetic in interfaces; ≤ 2 levels of indirection; no signed/unsigned mixing.
No dynamic allocation after init; RAII for resources; no exceptions.
Control flow braced;
switchcasesbreak;defaultwhen not exhaustive.Base‑class tests applied to derived classes; cover each virtual dispatch.
Any shall deviation documented in the file and approved.
Source: JOINT STRIKE FIGHTER AIR VEHICLE C++ CODING STANDARDS (Doc. No. 2RDU00001 Rev C, Dec 2005). This cheat sheet emphasizes the parts most useful for day‑to‑day development; consult the full standard for precise wording, rationales, and exceptions.


