-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmisra_cpp_rust_comparison_rules.csv
More file actions
We can make this file beautiful and searchable if this error is corrected: Illegal quoting in line 38.
179 lines (179 loc) · 41.3 KB
/
Copy pathmisra_cpp_rust_comparison_rules.csv
File metadata and controls
179 lines (179 loc) · 41.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
0.0.1;C3;Rust compiler checks for unreachable code, warnings will be generated. Unused \texttt{Result} types (Rust's error type) will also generate a warning, as do unused variables in general. Unused variable warnings can be promoted to compiler errors. (\url{https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unreachable-code})
0.0.2;C6;Rust does not prevent invariant controlling expressions (see example \texttt{if}, \texttt{while}), and does generally not give a warning. Rust can emit warnings if the comparison is useless due to type limits (\url{https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=57651b13a36c6e24c90ee9051277194f}). Regarding \texttt{for}-loops: Rust does act on ranges, so there is no controlling expression.
0.1.1;C6;Rust compiler gives warning for values that are assigned, but not read. Unused variables (which are destroyed before being observed) also throw a warning. Writing to values in a loop, before reading or observing them, does not trigger a warning. Therefore the rule is not exhaustively handled. Both warnings can be promoted to compilation errors.
0.1.2;C6;For a general unused return value, there is no warning given. Rust's error type \texttt{Result} produces an explicit compiler warning if its returned values are unused. Rust provides a language feature for annotating custom functions as \texttt{\#[must\_use]}, requiring callers to use the return value. If not, a compiler warning is emitted. Additionally, the standard library provides \texttt{\#[must\_use]} annotations for critical functions: \url{https://std-dev-guide.rust-lang.org/policy/must-use.html}. The warnings can be promoted to a compilation error.
0.2.1;C3; In Rust, declared variables have to be initialized before use. Unused variables throw a compilation warning, which is promotable to a compilation error (See example for rule 0.0.1, `Rust Reference: Variables p. 375/432').
0.2.2;C3;Per the rationale, this rule is specifically relevant when providing implementations for virtual functions in \Cpp. As Rust does not have a directly comparable concept, the same reasoning as for rule 0.2.1 applies. Unused variables will give a compiler warning in any case. As a remark, the compiler directive \texttt{\#[allow(unused)]} exists in Rust, which is comparable to \texttt{[[maybe\_unused]]} in \Cpp. Usage of this directive should be addressed in future Rust guidelines. The warning is promotable to a compilation error.
0.2.3;C3;Unused type alias produces compilation warning. Rust does not have an equivalent for an unnamed namespace, the equivalent for a namespace is a module. Unused type aliases in a named module also throw a compilation warning. The warnings are promotable to compilation errors.
0.2.4;C3;Functions with non-public visibility in structs and non-public modules with functions of any visibility produce warnings when unused. The warnings are promotable to compilation errors.
0.3.1;C6;Rust does not provide suspicious (imprecise) use warnings. Signalling for infinities exist, but the rationale behind the directive is not satisfied. Rust supports floating-point arithmetic, but appropriate usage depends on context and application-level constraints. By default Rust uses 64-bit floating-point numerical types, which lessens the accumulation of precision errors in common use cases.
0.3.2;C6;Naturally applies, as there can be arbitrary preconditions for any function defined by a programmer. Rust does not enforce preconditions automatically, but the type system and traits support this via \texttt{Option}s, \texttt{Result}s and the newtype pattern: \url{https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=7a2572eed534710a62a2572d980e728a}.
4.1.1;C5;No comparable standard exists for the Rust programming language yet, but should it exist, this rule would be required. Active work is being done: \url{https://github.com/rust-lang/rust/issues/113527}, \url{https://github.com/rust-lang/reference}.
4.1.2;C6;This rule naturally applies to the Rust programming language. Details in the rationale refer to specific \Cpp standards to identify deprecated features. Deprecated is already defined in rust: \url{https://rust-lang.github.io/rfcs/1270-deprecation.html}. The attribute emits a compilation warning by default, which can be promoted to a compilation error. See example.
4.1.3;C4;This rule naturally applies to code in safe Rust. Such code either works or panics. A non exhaustive list of behaviour considered undefined in Rust can be found in `Rust Reference, page 404/432'.
4.6.1;C4;The Rust borrow checker guarantees that only one mutable reference to any memory location exists at one point in time. This naturally enforces a sequencing of accesses. However, unsafe Rust still requires manual sequence awareness by developers. See `Rust Programming Language: Mutable References, Page 92/626'.
5.0.1;C2;Rust does not have a trigraph equivalent.
5.7.1;C3;Rust expects a closing marker for every opened comment block with \texttt{/\*}. In case there is not a matching number of closing markers, the Rust compiler throws an error.
5.7.2;C6;This directive naturally applies for Rust as well, as there is no restriction on code in comments.
5.7.3;C3;Rust does not have a line-splicing syntax like \Cpp. The line-splicing\texttt{\\} escape symbol only has effect within strings, comments are unaffected, as demonstrated in the example.
5.10.1;C3;Rust, like \Cpp, conforms to Unicode definitions to allow identifiers as described in `Rust Reference: Identifiers p. 12/432'. Identifiers are not allowed to have a reserved name, except when marked with the \texttt{r\#} prefix, and the usable character set is restricted in certain syntactical positions. The intended restriction the MISRA rule enforces is already enforced due to the identifier definition and syntax choice of Rust.
5.13.1;C3;The grammar accepted by the lexer for character and string literals is given in `Rust Reference p. 22/432'. Any expression not conforming to these rules will/should give a compilation error.
5.13.2;C3;Rust does not support octal escape sequences inside of string literals. Rust enforces termination, as can be seen in the example. For hexadecimal escape sequences in Rust, the lexer only accepts the literal in pairs of two. Therefore, the rationale does not apply anymore.
5.13.3;C3;The rationale for the rule is to avoid confusion, as in \Cpp a leading \texttt{0} marks an octal constant. In Rust, the leading \texttt{0} is ignored. To create an octal value, the \texttt{0o} prefix is required, leaving no room for confusion.
5.13.4;C3;Rust supports explicit suffixing of unsigned integer literals to specify their type. Common suffixes include \texttt{u8}, \texttt{u16}, \texttt{u32}, \texttt{u64}, \texttt{u128}, and \texttt{usize}. However, Rust does not have automatic integer promotion and its type system is platform-consistent. The rationale of this rule does not apply anymore.
5.13.5;C3;Rust does not have a \texttt{L} suffix to denote long integers. Only explicit suffixes are used (\texttt{u64}, \texttt{i64}).
5.13.6;C3;See explanation for rule 5.13.5, Rust uses explicit suffixes for \texttt{long} integers.
5.13.7;C3;Rust exposes only one String type (UTF8-encoded) in the standard library (`Rust Programming Language: What is a String? p.181/626'), as a String literal denoted as ``\texttt{..}''. Furthermore Raw string literals, Byte string literals, raw byte string literals and character literals exist (`Rust Programming Language, Table B-2 p. 608/626'), which are explicit in their type and can not be concatenated directly (see example).
6.0.1;C3;Function definitions in block scope are possible, but free functions always require a body in Rust, not just a declaration. Furthermore due to the syntax definition in Rust, no ambiguity as adressed by the rule can be forced in Rust (see example).
6.0.2;C6;Rust always requires explicit size for an array, external linkage included (see example).
6.0.3;C5;Part of the rationale for this rule is the influence of include ordering on program behaviour. Due to strict rules of unambigous names when using crates in Rust, this rule is partly satisfied. Prevention of cluttering during lookup still requires following this rule in Rust code (see example). A potential adaptation could involve the usage of `prelude' modules that are often used within the Rust ecosystem.
6.0.4;C6;Use of name \texttt{main} is possible in modules, rule also applies for Rust (see example).
6.2.1;C4;The explicit typing in Rust prevents the definition of two identical types within the same translation unit (compilation unit a.k.a. crate). However, some loop holes exist. The usage of the \texttt{no\_mangle} attribute allows one to define and link against two function versions of the same name. Ultimately, the resulting run-time behavior, as in the case of C/\Cpp, depends on the linker used for the final binary. The attribute is usable within safe Rust until edition 2024. From edition 2024, the attribute is marked \texttt{unsafe}. See example 6.2.1.
6.2.2;C3;Rust does not allow overloading like \Cpp, duplicate names (with or without different arguments) will always result in a compilation error (see example, also example for rule 6.0.4, 6.0.3).
6.2.3;C3;Multiple definitions of the same entity always result in a compilation error. The rule allows identical definitions in seperate translation units.In Rust even this will cause a compilation error, when ambigous definitions are imported/used.
6.2.4;C4;Rust has no notion of header files. This rule's goal is to prevent violations of the one-definition rule. This is possible in unsafe Rust (see 6.2.1).
6.4.1;C6;Rust allows shadowing in inner scopes (see example). However, the original rationale mentions developer confusion as the reason for the rule. Rust style guidelines advocate for variable rebinding as a form of clean code style. Additionally, global variable names are uppercase snakecase names and checked using lints.
6.4.2;C5;While Rust supports some form of inheritance using traits, Rust does not allow arbitrary method concealing. Traits fundamentally work by exposing all methods that they define on their implementation type. Structs can only shadow trait methods, but can never fully conceal them to consumers (see second example). Rust does not provide the possibility to have two functions with the same name and different parameter types. However, in a strict sense, the same behavior is present in Rust as it is in \Cpp, due to the way traits work in general.
6.4.3;C3;As Rust handles resolution of names in an explicit way with a hierarchical order, any kind of unqualified lookup is not possible Rust Reference: Namespaces p. 350/432' (also see reasoning for rules 6.0.2, 6.0.3, 6.0.4, 6.2.1).
6.5.1;C5;Rust has no notion of header files. External linkage has to be explicitly typed, see `Rust Reference: Functions p. 118/432'. Accessing the functions and objects defined with external linkage (such as \texttt{extern "C"}) is only possible within an \texttt{unsafe} context since edition 2024. However, similar behavior to headers can be achieved with Rust modules and using public visibility modifiers.
6.5.2;C4;It is possible to specify linkage in a non-compliant way (see example, unsafe since 2024).
6.7.1;C4;The rationale is possible race conditions. \texttt{mut static} variables in Rust can not be changed without an \texttt{unsafe} context. So possible Race conditions in a safe Rust context are guarded against, and the restriction on placement of static variables are not neccessary (see example).
6.7.2;C4;Rationale is uncontrolled mutability of global variables from arbitrary parts of the program, as well as unspecified initialization. See reasoning for rule 6.7.1, in Rust mutable global variables cannot be accessed without an \texttt{unsafe} block. For safe access, mutual exclusion mechanisms are enforced via the \texttt{Send} trait. However, the implementation of the \texttt{Send} trait can be done for arbitrary, custom data types within an \texttt{unsafe} context. Still, global variables can increase program complexity/unpredictability as described in the rationale.
6.8.1;C4;Rust's strong lifetime checks prevent an access after end of life. Any references require lifetime annotations, unless lifetime elision is possible. In that way the compiler can verify that objects are not accessed after their lifetime ends (see `Rust Reference: Lifetime bounds p. 323/432', `Lifetime elision p. 339/432', `Rust Programming Language: Validating References with Lifetimes p. 243/626ff'). \texttt{unsafe} blocks do not bypass lifetime checks, but they do allow for raw pointer operations, resulting in a necessary application of this rule in unsafe Rust. See example.
6.8.2;C3;Rust requires a lifetime annotation for returned references (which can never be valid for local variables), and additionally prohibits return of references to local variables. Returning a dangling pointer is safe to do in Rust, but results in a warning. Dereferencing the pointer is unsafe and will cause UB (see example). The warning can be promoted to a compilation error.
6.8.3;C3;Due to compiler checks of lifetime, assigning references without compatible lifetimes is not allowed (see example, also example and reasoning for rule 6.8.2, 6.8.1).
6.8.4;C4;\Cpp distinction between methods callable on \textit{lvalue} and \textit{rvalue} objects does not directly correspond to a mechanism in Rust. The rationale of preventing dangling references is covered by lifetime checks, for member and non-member functions alike. (see rule 6.8.1). Some checks are in place for unsafe Rust: \url{https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dangling-pointers-from-locals}.
6.9.1;C3;Multiple definitions with the same name are not allowed and overloading does not exist (see example).
6.9.2;C3;Rust integer types for the most part include their size in the type name. The only exception is the type \texttt{usize} and \texttt{isize} (`Rust Programming Language: Integer Types p. 48/626').
7.0.1;C6;Rust has explicit conversion from type \texttt{bool} (see `Rust Reference: Type cast expressions p. 205/432').
7.0.2;C4;Rust has no implicit or explicit conversion to type \texttt{bool} (see `Rust Reference: Type cast expressions p. 205/432').
7.0.3;C4;Explicit cast from char to an integer type and the reverse is possible (`Rust Reference: Type cast expressions p. 205/432'). However, the value of a char is well-defined and unicode-safe. The check can be circumvented in unsafe Rust.
7.0.4;C3;Rust enforces matching left- and right-hand types during compilation. It is not possible to shift with values greater than the \textit{lvalue} type.
7.0.5;C3;Rust does not have a comparable integral promotion like \Cpp from smaller to larger integer types. Promotion has to be explicit (see example).
7.0.6;C6;Compile time assignments are checked for appropriateness, during runtime assignments with e.g. overflow will result in a panic if running in debug mode (see example).
7.11.1;C4;Rust does not have the notion of raw pointers in a non-\texttt{unsafe} context, including the \texttt{nullptr} (`Rust Reference: Raw Pointers p. 289/432'). Its equivalent, \texttt{std::ptr::null}, is not of type integer, but uses generics to match its return value.
7.11.2;C3;An array is a fixed-size sequence in Rust, passing as a reference is possible. In contrast to \Cpp, the reference is a \textit{slice} type, not a raw pointer, and bounds are still checked during compilation and runtime `Rust Reference: Array types, Slice types p. 279/432ff' (see example). Arrays passed over FFI boundaries are out of scope.
7.11.3;C3;Function item and function pointer types are explicit in Rust, no ambiguity is possible; `Rust Reference: Function item types p. 284/432'. The rationale of the rule does not apply to Rust due to its stricter type system.
8.0.1;C6;Rust has less operators and expressions (`Rust Reference: Expression precedence p. 180/432'), but the rule naturally applies.
8.1.1;C3;Rationale is to prevent undefined behaviour, if the lambda is called after the object's lifetime ends. In Rust, lifetime checks prevent this (see example).
8.1.2;C3;Rationale is to prevent dangling pointers in the lambda (in a Rust closure). Due to lifetime checks, this is not possible in Rust (see rule 8.1.1). The misleading or confusing interpretation problem is solved by Rust's choice of syntax: the \texttt{move} keyword.
8.2.1;C4;In Rust, the \texttt{dyn} keyword can be used to describe trait behaviour without specifying an explicit type at compile time. Cast to a specific type (corresponding to a derived class in \Cpp) can be done with the call \texttt{downcast\_ref::\textless DerivedType\textgreater}, which corresponds to this rule's requirements; `Rust Programming Language: Defining a Trait for Common Behavior p. 462/626'.
8.2.2;C3;Type casts in Rust are explicit. The rationale for this rule is prevention of implicit or hard to identify type casts should be satisfied by this (see `Rust Reference: Type cast expressions p. 205/432').
8.2.3;C4;Rust enforces strict ownership and borrowing rules that prevent casting from removing immutability or mutability qualifiers (`Rust Reference: Type cast expressions p. 205/432').
8.2.4;C4;Rust enforces strict type safety and does not allow arbitrary casts between function pointers and other types. Only safe and explicit casts are permitted, ensuring that undefined behavior is avoided (`Rust Reference: Type cast expressions p. 205/432').
8.2.5;C4;Rust equivalent would be function \texttt{std::mem::transmute}, which can only be used in an \texttt{unsafe} context.
8.2.6;C4;Cast from pointer to pointer, and pointer to address and reverse are allowed. Furthermore is this section of the reference not fully documented. This rule is still safely handled, as all pointer dereferences have to be in an \texttt{unsafe} block (`Rust Reference: Type cast expressions p. 205/432').
8.2.7;C4;Interpreting a pointer type as integer will yield that pointer's address in Rust. Accessing a pointer has to be handled in an \texttt{unsafe} block (`Rust Reference: Type cast expressions p. 205/432'). The rationale of the rule still holds in \texttt{unsafe} context. However, such casts have to reside within \texttt{unsafe} blocks, providing developers a strong indication that they have to pay extra attention for the contained code.
8.2.8;C4;Rust has no direct correspondence to specific pointer types, but pointer access is handled in an \texttt{unsafe} block (`Rust Reference: Type cast expressions p. 205/432').
8.2.9;C4;Rust's \texttt{typeid} equivalent uses a strongly typed approach, that enforces a runtime check, and therefore there is no ambiguity (see example).
8.2.10;C6;Recursion is possible, therefore this rule applies (see example).
8.2.11;C4;Rust does not have a direct equivalent to ellipsis (variadic functions), as variadic functions are only allowed in external (C-)function blocks (`Rust Reference: Function parameters p.78/432', \url{https://doc.rust-lang.org/reference/items/external-blocks.html#r-items.extern.v}).
8.3.1;C3;Rust utilizes only explicit integer promotions, due to the type system applying the \texttt{-} operator to an unsigned integer results in a compilation error (see example).
8.3.2;C3;Rationale for this rule is the integral promotion triggered by the operator. As Rust only has explicit promotion, this rule does not apply (see example for 8.3.1).
8.7.1;C4; Dereferencing a raw pointer is an unsafe operation in Rust, therefore the rationale behind this rule is satisfied (`Rust Reference: Raw Pointers p. 289/432').
8.7.2;C4;Operations on raw pointers and dereferencing the result is an unsafe operation in Rust, therefore the rationale behind this rule is satisfied (`Rust Reference: Raw Pointers p. 289/432').
8.9.1;C4;Comparison between pointers is an unsafe operation in Rust, therefore the rationale behind this rule is satisfied (`Rust Reference: Raw Pointers p. 289/432', see example).
8.14.1;C6;Persistent side effects are possible (see example).
8.18.1;C4;The Rust equivalent to \texttt{std::memcpy} is \texttt{std::ptr::copy}, which is semantically equivalent to \texttt{std::memmove} per documentation: \url{https://doc.rust-lang.org/std/ptr/fn.copy.html}.
8.18.2;C3;In contrast to \Cpp, the return type of an assignment is always \texttt{()}. Due to the strict type system, there is no ambiguity (see example).
8.19.1;C2;Sequencing of expressions uses blocks \texttt{\{\}} in Rust, the comma operator does not exist. This can be seen as less ambiguous (see example).
8.20.1;C6;Const values are evaluated at compile time in Rust, overflows won't always cause a compilation error – but a panic at runtime. To force wrapping, explicit functions have to be used (see example).
9.2.1;C3;Rust syntax for explicit type conversion is unambiguous. The rationale of accidental release of resources due to unclear syntax is solved by this (see example). Resources in Rust are usually dropped by implementing the \texttt{Drop} trait. Once a locked \texttt{Mutex} is dropped, its resource is released. However, it is syntactically not possible to construct and release such a mutex while causing ambiguity.
9.3.1;C3;In Rust, iteration and selection-statements always require curly braces \texttt{\{\}}, satisfying the rationale of unambiguous compound-statements (`Rust Reference: Loops and other breakable expressions p. 230/432').
9.4.1;C6;Termination with an \texttt{else} statement is not required in Rust (see example).
9.4.2;C3;Rust has no \texttt{switch} statement, the closest equivalent could be a \texttt{match} expression. The rules ensure the complex structure of a switch statement is ``well-formed''. Rust \texttt{match} statements are required to be exhaustive and have clear pattern matching syntax using logical boolean operators, removing all of the ambiguity.
9.5.1;C3;Rationale for this rule is the prevention of unclear number of iterations in a for loop. Due to strict type checks and immutability of the chosen loop index variable, equivalent dangers like in legacy for statements in \Cpp are not present (see example).
9.5.2;C2;In Rust, the \texttt{for} loop initializer typically uses ranges or iterators, which do not utilize function calls in the same manner as a for-range-initializer (`Rust Reference: Predicate pattern loops p. 231/431'). An adaptation of the rule is not required, as the rationale states that the rule shall prevent UB related to object lifetime violations. Due to Rust's borrow checker, these do not occur.
9.6.1;C2;Rust does not have a \texttt{goto} statement, which inherently satisfies this rule and prevents the associated risks.
9.6.2;C2;See explanation rule 9.6.1
9.6.3;C2;See explanation rule 9.6.1
9.6.4;C3;In Rust, functions that do not return are indicated with the \texttt{!} type. This ensures that the function does not return to the caller. The compiler errors if a function does return instead (see example and `Rust Reference: Never type p. 277/432').
9.6.5;C3;Rust's strong type system enforces that functions with a non-void return type must return a value on all paths. The Rust compiler checks for this at compile time, ensuring that all code paths in a function return a value of the specified type, even with abstract return types (see example and `Rust Reference: Abstract return types p. 297/432').
10.0.1;C2;Rust does not have declaration without initialization before use (`Rust Reference: Variables p. 375/432').
10.1.1;C3;Rust's mutability rules enforce that references are either mutable or immutable. Immutable references (\texttt{\&T}) cannot be used to modify the referenced value, instead explicit \texttt{mut} keyword is required (see example and `Rust Programming Language: Variables and Mutability p. 43/626').
10.1.2;C4;Rust's equivalent is \texttt{core::ptr::read\_volatile}, behaving like in C (\url{https://doc.rust-lang.org/core/ptr/fn.read_volatile.html}).
10.2.1;C3;Compared to \Cpp enums, Rust enums are more flexible, such that each field can have an arbitrary type. This satisfies the rationale of an obvious enum type for the user (`Rust Reference: Enumerations p. 88/432').
10.2.2;C3;Rust has explicit types and namespaces for enums (`Rust Reference: Enumerations p.88/432').
10.2.3;C3;See explanation for rule 10.2.2
10.3.1;C3;Rust modules (namespace equivalent) are always named (`Rust Reference: Modules p. 68/432').
10.4.1;C4;Rust \texttt{asm!} macro requires an \texttt{unsafe} block to use (see example).
11.3.1;C3;Rust arrays are fixed-size and bound check during compilation. Rust's general move semantics apply, as the Array type does not implement the \texttt{Copy} trait, thus the rationale of this rule is satisfied (`Rust Reference: Array types p. 278/432', `Copy Trait: p. 345/432').
11.3.2;C4;Rust allows multiple levels of pointer indirection (see example). While the example code is safe Rust, the usage of pointers via dereferencing them is an unsafe operation. The multi-level pointer indirection only becomes an issue in unsafe Rust, where they can be used. This decision aligns closer to the MISRA rule rationale.
11.6.1;C4;Rust enforces RAII, declaring variables requires initialization before they can be used on any control flow path (`Rust Reference: Declaration statements p. 176/432', `Rust Reference: Variables p. 375/432').
11.6.2;C4;\texttt{MaybeUninit} can be used to initialize an empty value and read it from it within an \texttt{unsafe} context.
11.6.3;C3;In Rust values of implicitly-specified enumeration constants are checked for uniqueness during compile time (see example).
12.2.1;C2;Rust does not have Bitfields or an equivalent.
12.2.2;C2;Rust does not have bit-fields or an equivalent.
12.2.3;C2;Rust does not have bit-fields or an equivalent.
12.3.1;C5;Rust's \texttt{union} implementation mitigates risks of dropped memory regions or implicit write operations, but this behaviour can explicitly be added to unions. Therefore the rule can be applied to Rust as well (`Rust Reference: Initialization of a Union p.95/432').
13.1.1;C2;Rust has no direct equivalent to inheritance and virtual inheritance. Due to strict typing, runtime polymorphism is possible in a different, explicit way, without similiar problems like diamond hierarchies (see example).
13.1.2;C2;As Rust does not have virtual classes, the behaviour is less ambigous (see example 13.1.1).
13.3.1;C2;Rust's equivalent of virtual functions are trait implementations. Trait implementations are explicit (impl block). This eliminates the rule's rationale fo exidental overrides through Rust's language design (see example).
13.3.2;C2;Rust does not support default arguments in function signatures, the extend of confusing override behaviour is what is described in rule 13.3.1.
13.3.3;C6;Rust does not allow unnamed function arguments. Arguments must be named and explicitly typed (`Rust Programming Language: Functions p. 56/626').
13.3.4;C2; Rust does not have a notion of virtual pointer-to-member pointers (`Rust Reference: Raw Pointers p. 289/432').
14.1.1;C6;Rust allows both public and non-public members simultaniously. Therefore the rule applies, even if nuances such as static keyword and protected functions are different in Rust (see example).
15.0.1;C5;Rationale is to address vulnerabilities of ``Rule of Zero'', ``Rule of Five'', and \Cpp11 ``Rule of Three''. Rust handles these special member functions via the special traits: \texttt{Copy}, \texttt{Clone}, \texttt{Drop}. Intricacies of \Cpp implementations of special member functions are different in Rust. This rule applies in a general sense, but would require careful evaluation to apply to Rust.
15.0.2;C3;In Rust, move semantics are the default behaviour for types not implementing the \texttt{Copy} trait. The \texttt{Copy} trait has an explicit application rule without ambiguity, and forces implementation of the \texttt{Clone} trait as well (see example).
15.1.1;C3;Rust object construction and destruction is done differently. For construction, typically an associated function (per convention named new) without self (or this) reference is used, to return a value of the type being constructed. The problem addressed by this rule does not occur. Destruction requires implementation of the Drop trait, which has no access to a dynamic trait implementation and is called automatically.
15.1.2;C3;Rust does initialization in an explicit way. A comparable mechanism to class inheritance in Rust is Supertraits. Due to explicit typing and initialization, those do not exhibit the same ambiguous behaviour when initialized. (`Rust Reference: Supertraits 108/432').
15.1.3;C2;Rust has only explicit initialization, without implicit conversions. The closest equivalent is the \texttt{tuple struct}, but these are not affected by this rule (see example).
15.1.4;C3;On function entry, space for Rust objects is reserved on the stack. Initialization has to be finished before access, this is enforced during compile time (`Rust Reference: Variables p. 375/432').
15.1.5;C2;Rationale behind this rule is unclear behaviour under special overload resolution rules. Rust does not have an overload mechanism, therefore no need to address this.
15.8.1;C3;This rule is concerned with undefined behaviour during copy and move assignments, when assigning to self. When providing user-defined implementations of Rust's \texttt{Copy} trait, the \texttt{Clone} trait is required. Furthermore, implementing the \texttt{Copy} trait is not possible for heap-allocated types (like \texttt{Box}). Here only a \texttt{Clone} trait implementation is possible. Due to Rust's move mechanics, self-assignments is not an issue (see example).
16.5.1;C2;Rust implements operators via traits. Custom implementations (overloading) \texttt{\&\&} and \texttt{||} is not possible: \url{https://doc.rust-lang.org/std/ops/index.html}.
16.5.2;C2;Rust provides no operator trait for \texttt{\&}.
16.6.1;C3;The rationale behind this rule is unexpected implicit type conversions for symmetrical member functions. For Rust, overriding a (symmetric) operator by implementing it's trait, is explicitly typed. Therefore this problem does not arise (see example).
17.8.1;C2;Rust does not have overloaded functions. The rationale behind this rule is developer confusion, because overload resolution in conjunction with explicit specialization might lead to unexpected results. Rust restricts specialization, function names are still unique (see example and `Rust Reference: Generic functions p. 79/432').
18.1.1;C2;Rust does not have an exception model like \Cpp. Instead errors are categorized in recoverable and unrecoverable errors. For Rust, the special type \texttt{Result} exists, to catch expected runtime errors. Unexpected runtime errors will be caught by a panic handler. \texttt{Result}s can have arbitrary types, including referenced memory. Due to borrow checks, this rule might possibly not apply, but in general the error handling is different (`Rust Programming Language: Error handling p. 196/626').
18.1.2;C2;Rationale is preventing implementation-defined program termination, based on \Cpp specific exception handling. As Rust does not have a similar exception mechanism, no application of this rule is obvious (`Rust Programming Language: Error handling p. 196/626').
18.3.1;C2;Rust employs a panic handler, but its purpose is only with regard to unrecoverable errors. Exceptions in \Cpp are purposed to handle all types of errors. However, panics are non-recoverable. Therefore the concept of catchable exceptions does not exist in Rust (`Rust Programming Language: Error handling p. 196/626').
18.3.2;C2;Rust's \texttt{Result} type provides the possibility of arbitrary error types. Due to explicit types, the rationale (losing information due to slicing) behind this rule is not satisfied. Also, as stated in rule 18.3.1, Rust has no exception types, making this rule not applicable.
18.3.3;C2;This problem can not occur in Rust, as initialization before access is enforced at compile time (`Rust Reference: Variables p. 375/432').
18.4.1;C2;Rationale is prevention of implementation-defined termination if an exception occurs during call of a destructor. As Rust handles release of resources automatically based on lifetimes, this is not required in general. Additionally, the only way to return an error message from functions is either through the type system or a panic. There are no ``surprises''.
18.5.1;C5;Rust has no equivalent to \texttt{noexcept} therefore there is no automatic passing of errors to calling functions. Different methods in Rust exist to propagate errors, some of which may lead to accidental omittance by the developer (see example).
18.5.2;C6;Applies, as Rust has functions to terminate execution (see example).
19.0.1;C5;Rust uses different control flow syntax, but typos, as outlined in the rationale, can still cause the same type of error (see example).
19.0.2;C2;Some behaviour of Rust macros is improved, e.g., strict type checks (see example) and a different syntax than function calls. Rust procedural macros generate Rust code, including function-like macros. The resulting code is type checked and compiled as if a human would have written it. The rationale of the rule does not apply (`Rust Reference: Procedural Macros p. 47/432').
19.0.3;C6;Rationale is readability, thus this rule naturally applies (see example).
19.0.4;C2;The most direct equivalent to preprocessor macros in Rust are attributes. Different categories of attributes exist, that mimic \Cpp macros. A difference in method can be observed, as Rust attributes can be used to activate or deactivate code based on conditions (see example), but do not have an equivalent to \texttt{\#undef}. A complete analysis checking underlying grammars for equivalence is out of scope. The rationale behind the rule is to prevent developer confusion, and for the case of attributes in Rust, it can be confusing to see exactly how code behaves if attribute configuration is used extensively (`Rust Reference: Attributes p. 141/432').
19.1.1;C2;This rule addresses undefined behaviour of the defined preprocessor operator, thus is not applicable to Rust.
19.1.2;C2;Attributes in Rust are directly applied to a code object, stretching the scope of effect over multiple files (or even code objects in the same file) is not possible (`Rust Reference: Attributes p. 141/432').
19.1.3;C4;If configuration attributes are used to configure the code base, non-defined features cause a compilation warning, which can be promoted to an error (see example).
19.2.1;C3;Rationale is to prevent confusing behaviour and unexpected redefinition due to collisions in complex include structures. Due to strict import rules and compile time checks against redefinition, the problems addressed by this rule are solved at compile time in Rust (see example).
19.2.2;C5;As Rust does not use filenames, but rather crate names, and instead of the \texttt{include} directive the \texttt{use} directive, the guideline is not directly applicable. In general some restriction on valid import syntax in Rust is required (see reasoning guideline 19.2.3).
19.2.3;C4;File names are restricted by OS. The sequences given in the rule would also lead to invalid Rust import names.
19.3.1;C2;Rationale for this rule is unspecified order of evaluation for these operators. Rust does not have a direct equivalent. Macro invocation in Rust expands the macro at compile time, similar to the \Cpp preprocessor, but offers unique fragment-specifiers to match a Rust syntax fragment. To satisfy this rule, Rust macros would be required to be more concise, reducing ambiguity. In the given example, an equivalent Rust macro call is shown. Due to missing language features, to receive similar functionality to the \texttt{\#} and \texttt{\#\#} operators, the example given for the macro invocation heavily relies on function calls, solving the task at runtime instead of compile time (see example, `Rust Reference: Macros p. 35/432' to `p. 42/432').
19.3.2;C2;See explanation and example rule 19.3.1.
19.3.3;C2;Rationale is differing expanding behaviour of parameters, depending on the context. As with rule 19.3.2, Rust does not need to address this due to rule 19.3.1.
19.3.4;C4;The rationale is to prevent unexpected behaviour due to textual replacement in \Cpp macros, instead of handling macro arguments like parameters to a function call. In Rust, meta-variables are used to match macro parameters, resulting in behaviour that resembles type checks. Where in \Cpp operator precedence and textual replacement might lead to unexpected behaviour, Rust matches operands as expressions (see example). Rust's mechanism adds safety for the given rationale.
19.3.5;C2;Rationale is undefined behaviour due to textual replacement resulting in valid code with undefined semantics. As Rust has a different macro syntax and semantic, this rule is specific to \Cpp (`Rust Reference: Macros p. 35/432').
19.6.1;C2;Rationale is implementation-defined behaviour of the \Cpp compiler. Rust does not have an official standard. From a technical perspective, all features can be considered to be implementation-specific. However, the Rust foundation maintains a reference \url{https://doc.rust-lang.org/reference/}. To keep the spirit of the MISRA rule, we categorize the item as class C1, since the \texttt{\#pragma} is not available within Rust as a concept.
21.2.1;C1;Rationale is undefined behaviour in these stdlib functions.
21.2.2;C1;Does naturally not apply.
21.2.3;C1;Does naturally not apply.
21.2.4;C1;Does naturally not apply.
21.6.1;C6;Naturally applies to Rust, as dynamic memory exists in Rust as well. General problems like resource exhaustion cannot be mitigated in general.
21.6.2;C5;Rust's lifetime management guarantees this. When not specified, lifetime elision is used. Additionally explicit lifetime annotations are required by the compiler, where automatic elision is not possible. Variables going out of scope will call their destructor equivalent automatically (provided by the \texttt{Drop} trait implementation). A natural adaptation of this rule to Rust should include rules to address explicit \texttt{Drop} implementations by a user (`Rust Reference: Lifetime elision p. 340/432', see example for rule 21.6.4).
21.6.3;C4;Rationale is that specific handling of dynamic memory leads to potential issues with alignment, object lifetimes, and user implementations of \texttt{new} or \texttt{delete} operators, all resulting in undefined behaviour. Rust does not have such specific memory management in non-unsafe code. For dynamic memory allocation in a safe context, only specific types like \texttt{Box} or \texttt{Vec} types exist (`Rust Reference: Memory allocation and lifetime p. 374/432'). See rule 21.6.2 for the \texttt{Drop} trait.
21.6.4;C2;Rust does not allow global overwrite of deallocation logic like in \Cpp. See rule 21.6.2 for the \texttt{Drop} trait.
21.6.5;C4;Full type definition is required in Rust before usage, this includes manual deletion via the \texttt{Drop} trait implementation (see explanation for rule 0.2.1 and rule 21.6.4).
21.10.1;C1;Rule naturally not applicable, as this is specific to the \Cpp stdlib.
21.10.2;C1;Rule naturally not applicable, as this is specific to the \Cpp stdlib. These functions allow bypassing the normal function return mechanism. This rule addresses concerns of safety standards like ISO 26262 (Part 6, Table 6), where ``single-entry single-exit'' principle is encouraged.
21.10.3;C1;Rule naturally not applicable, as this is specific to the \Cpp stdlib. Signal handling is per the rationale defined in ISO 9899.
22.3.1;C5;Rationale is the runtime evaluation of \texttt{assert}, when compile time evaluation with \texttt{static\_assert} would be possible. Rust provides the \texttt{assert!} macro, that evaluates const expressions at compile time, and non-const expressions at runtime. The underlying rationale of this rule is addressed. Due to the duality of the macro, developer expectations of when the \texttt{assert} macro is evaluated might not be clear at a glance (see example).
22.4.1;C2;Rust uses the \texttt{Result} type to handle errors.
23.11.1;C2;Rationale is avoiding creation of raw pointers as an intermediary step. Rust without unsafe code does not allow those raw pointers (`Rust Reference: Raw Pointers p. 289/432').
24.5.1;C1;Rules does naturally not apply.
24.5.2;C1;Rationale is undefined behaviour in cases of memory overlap, potential overlap, is not trivially copyable. With regard to \texttt{memcpy}, refer to rule 8.18.1 for more insight. Rust does not have a direct equivalent to \texttt{memcmp}.
25.5.1;C1;Does naturally not apply to Rust.
25.5.2;C1;Does naturally not apply to Rust.
25.5.3;C1;Does naturally not apply to Rust.
26.3.1;C2;Does naturally not apply to Rust.
28.3.1;C2;Does naturally not apply, as the rationale is implementation-defined copy behaviour of special template parameters.
28.6.1;C4;Rationale is the \texttt{std::move} function not moving content of const objects. This specific rule is not applicable to Rust, as moved values are inaccessible at the original side in Rust (see rule 15.0.2).
28.6.2;C2;Rationale is idiomatic use of perfect forwarding in \Cpp, consistently preserving the value category. There is no clear equivalent in Rust that matches this exact rule. In general the ownership model addresses the underlying problem differently (`Rust Programming Language: Understanding Ownership' p. 75/626).
28.6.3;C2;Potentially moved refers to objects created by calling \texttt{std::move}, \texttt{std::forward}, or an equivalent \texttt{static\_cast}. Similar to rule 28.6.2, Rust's ownership mechanism addresses the underlying issues differently (see rule 28.6.2).
28.6.4;C1;Rationale is preventing the programmer from ignoring an unexpected empty result, when the goal might have been to purge by calling \texttt{std::erase} in conjunction.
30.0.1;C1;Rationale is undefined, unspecified, and implementation-defined behaviour associated with those functions. Rule does naturally not apply.
30.0.2;C1;Rationale is specifics of the C \texttt{FILE *} abstraction.