Skip to content

Commit 82b7808

Browse files
x0rwgithub-actions[bot]
authored andcommitted
Add guideline for issue #21
Co-authored-by: x0rw <[email protected]>
1 parent ddd254d commit 82b7808

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

src/coding-guidelines/associated-items.rst

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,88 @@
55

66
Associated Items
77
================
8+
9+
.. guideline:: Guideline Test
10+
:id: gui_rvILMc67B1g0
11+
:category: advisory
12+
:status: draft
13+
:release: 1.1.1-1.1.1
14+
:fls: fls_vjgkg8kfi93
15+
:decidability: decidable
16+
:scope: module
17+
:tags: stack-overflow
18+
19+
Any function shall not call itself directly or indirectly
20+
21+
.. rationale::
22+
:id: rat_3iPWGSiQA78N
23+
:status: draft
24+
25+
Recursive functions can easily cause stack overflows, which may result in exceptions or, in some cases, undefined behavior (typically some embedded systems). Although the Rust compiler supports `tail call optimization <https://en.wikipedia.org/wiki/Tail_call>`_\ , this optimization is not guaranteed and depends on the specific implementation and function structure. There is an `open RFC to guarantee tail call optimization in the Rust compiler <https://github.com/phi-go/rfcs/blob/guaranteed-tco/text/0000-explicit-tail-calls.md>`_\ , but this feature has not yet been stabilized. Until tail call optimization is guaranteed and stabilized, developers should avoid using recursive functions to prevent potential stack overflows and ensure program reliability.
26+
27+
.. non_compliant_example::
28+
:id: non_compl_ex_RpjYJykw9H2N
29+
:status: draft
30+
31+
The below function concat_strings is not complaint because it call itself and depending on depth of data provided as input it could generate an stack overflow exception or undefine behavior.
32+
33+
.. code-block:: rust
34+
35+
// Recursive enum to represent a string or a list of `MyEnum`
36+
enum MyEnum {
37+
Str(String),
38+
List(Vec<MyEnum>),
39+
}
40+
41+
// Concatenates strings from a nested structure of `MyEnum` using recursion.
42+
fn concat_strings(input: &[MyEnum]) -> String {
43+
let mut result = String::new();
44+
for item in input {
45+
match item {
46+
MyEnum::Str(s) => result.push_str(s),
47+
MyEnum::List(list) => result.push_str(&concat_strings(list)),
48+
}
49+
}
50+
result
51+
}
52+
53+
.. compliant_example::
54+
:id: compl_ex_vJx0vYocTHCz
55+
:status: draft
56+
57+
tete
58+
59+
.. code-block:: rust
60+
61+
// Recursive enum to represent a string or a list of `MyEnum`
62+
enum MyEnum {
63+
Str(String),
64+
List(Vec<MyEnum>),
65+
}
66+
67+
/// Concatenates strings from a nested structure of `MyEnum` without using recursion.
68+
/// Returns an error if the stack size exceeds `MAX_STACK_SIZE`.
69+
fn concat_strings_non_recursive(input: &[MyEnum]) -> Result<String, &'static str> {
70+
const MAX_STACK_SIZE: usize = 1000;
71+
let mut result = String::new();
72+
let mut stack = Vec::new();
73+
74+
// Add all items to the stack
75+
stack.extend(input.iter());
76+
77+
while let Some(item) = stack.pop() {
78+
match item {
79+
MyEnum::Str(s) => result.insert_str(0, s),
80+
MyEnum::List(list) => {
81+
// Add list items to the stack
82+
for sub_item in list.iter() {
83+
stack.push(sub_item);
84+
if stack.len() > MAX_STACK_SIZE {
85+
return Err("Too big structure");
86+
}
87+
}
88+
}
89+
}
90+
}
91+
Ok(result)
92+
}

0 commit comments

Comments
 (0)