←back to thread

327 points AareyBaba | 9 comments | | HN request time: 0.945s | source | bottom
Show context
anonymousiam ◴[] No.46184727[source]
The same is true for the software that runs many satellites. Use of the STL is prohibited.

The main issue is mission assurance. Using the stack or the heap means your variables aren't always at the same memory address. This can be bad if a particular memory cell has failed. If every variable has a fixed address, and one of those addresses goes bad, a patch can be loaded to move that address and the mission can continue.

replies(7): >>46185566 #>>46187219 #>>46188652 #>>46189307 #>>46190613 #>>46191199 #>>46196185 #
5d41402abc4b ◴[] No.46188652[source]
> Using the stack or the heap means your variables aren't always at the same memory address

Where do you place the variables then? as global variables? and how do you detect if a memory cell has gone bad?

replies(1): >>46189537 #
cminmin ◴[] No.46189537[source]
your programs have a data segment. its not the heap nor the stack... and it can be (depending on loader/linker) a source of reliable object->address mappings as its not dynamically populated.
replies(1): >>46189796 #
1. repelsteeltje ◴[] No.46189796[source]
That sounds like your answer is: "Yes, global variables".

That may be a perfectly good solution in many embedded environments, but in most other context's global variables are considered bad design or very limiting and impractical.

replies(3): >>46190061 #>>46190686 #>>46190979 #
2. izacus ◴[] No.46190061[source]
They're considered impractical mostly because language tooling doesn't support them appropriately.
replies(1): >>46190374 #
3. repelsteeltje ◴[] No.46190374[source]
Can you elaborate?

For instance, how would better tooling help with storing a TCP buffer in global memory?

replies(2): >>46190568 #>>46192580 #
4. ◴[] No.46190568{3}[source]
5. TuxSH ◴[] No.46190686[source]
> global variables are considered bad design

Global mutable variables, and they usually tend to be grouped into singletons (solving initialization issues, and fewer people bat an eye)

replies(1): >>46196544 #
6. ◴[] No.46190979[source]
7. tatjam ◴[] No.46192580{3}[source]
As a quick example, compare doing embedded work with a C static uint8_t[MAX_BUFFER_SIZE] alongside a FreeRTOS semaphore and counter for the number of bytes written, vs using Rust's heapless::Vec<u8, MAX_BUFFER_SIZE>, behind a embassy Mutex.

The first will be a real pain, as you now have 3 global variables, and the second will look pretty much like multi-threaded Rust running on a normal OS, but with some extra logic to handle the buffer growing too big.

You can probably squeeze more performance out of the C code, specially if you know your system in-depth, but (from experience) it's very easy to lose track of the program's state and end up shooting your foot.

replies(1): >>46195150 #
8. repelsteeltje ◴[] No.46195150{4}[source]
Okay, fair enough.

So it's mostly about the absence of abstraction, in the C example? C++ would offer the same convenience (with std::mutex and std::array globals), but in C it's more of a hassle. Gotcha.

One more question because I'm curious - where would you anticipate C would be able to squeeze out more performance in above example?

9. RealityVoid ◴[] No.46196544[source]
Even global mutable variables are a problem only because they lend to spaghetti code and messy state handling if you use them in multiple places. But you could just... make a global variable and then handle it like you would a variable init with malloc. No functional issue there.