Author Topic: Converting assembly to C  (Read 25033 times)

0 Members and 12 Guests are viewing this topic.

Offline Picuino

  • Super Contributor
  • ***
  • Posts: 1461
  • Country: es
    • Picuino
Re: Converting assembly to C
« Reply #50 on: March 31, 2025, 03:24:45 pm »
I asked the example where you cannot replace it with conventional code which don't use goto.

This does not exist. In structured programming you can ALWAYS replace goto with other operations.

We can only talk about where goto may be more effective/fast/clean than other solutions. And as you rightly pointed out, goto can probably be more effective but at the same time more insecure and error prone.
« Last Edit: March 31, 2025, 03:27:00 pm by Picuino »
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 5733
  • Country: Earth
Re: Converting assembly to C
« Reply #51 on: March 31, 2025, 03:37:38 pm »
On the other hand...

Quote
Disadvantages of goto in C

I didn't ask for copy-pasted quotes from some online article.

I asked a simple and specific question - can you provide an example where goto is truly necessary and cannot be replaced with conventional structured code that avoids goto? Do you have one?

Articles are written by people like everyone else, and people make mistakes. That's why you should think for yourself instead of blindly relying on something just because someone wrote it on the internet.

This does not exist. In structured programming you can ALWAYS replace goto with other operations.

Well. I'm glad you finally admitted it. :)

We can only talk about where goto may be more effective than other solutions. And as you rightly pointed out, goto can probably be more effective but at the same time more insecure and error prone.

Are you serious? What makes you think that avoiding goto leads to more insecure and error-prone code? :o

Doesn't the example provided by the topic author clearly demonstrate that using goto results in code that even the original author struggles to understand? Do you really consider that to be more secure and less error-prone than straightforward, readable code, where the author fully understands what they are doing and which can be easily reviewed and analyzed for errors? 


« Last Edit: March 31, 2025, 03:44:47 pm by radiolistener »
 

Offline Picuino

  • Super Contributor
  • ***
  • Posts: 1461
  • Country: es
    • Picuino
Re: Converting assembly to C
« Reply #52 on: March 31, 2025, 03:43:29 pm »
You misunderstood me. I am agreeing with you by saying that goto is error prone.

I am just saying that goto is used in C and there are not always the reasons you gave for avoiding it at all costs.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Converting assembly to C
« Reply #53 on: March 31, 2025, 04:26:07 pm »
Here equivalent code but with no goto:
Code: [Select]
void foo() {
    if (!doA()) {
        return;
    }
    if (!doB()) {
        undoA();
        return;
    }
    if (!doC()) {
        undoB();
        undoA();
        return;
    }

    /* everything has succeeded */
    return;
}
This pattern is problematic when undoA() is nontrivial, because it is duplicated in the code: a very common bug pattern occurs when only one of them is updated but the other one is missed.  This is the underlying reason why in the Linux kernel the goto-based error recovery pattern is used (especially when any kind of locking is involved; multiple concurrent locks are notoriously easy to mess up) instead of duplicating the cleanup cases: the duplicates way too often fall out of sync during maintenance.

Religiously avoiding goto is at least as stupid as using it when it is not necessary.   Don't trust any rule of thumb so far as to claim it always applies; they never do.

The other pattern to avoid goto is to use a separate state variable.  I've shown an example of that in the thread Picuino linked to, related to selective cleanup.  Because this pattern tracks the cleanup needs using a separate variable, it has its own cognitive cost for us humans, and may not always be superior to a well-done goto pattern.
« Last Edit: March 31, 2025, 04:31:15 pm by Nominal Animal »
 
The following users thanked this post: newbrain

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 5733
  • Country: Earth
Re: Converting assembly to C
« Reply #54 on: March 31, 2025, 06:05:28 pm »
This pattern is problematic when undoA() is nontrivial, because it is duplicated in the code: a very common bug pattern occurs when only one of them is updated but the other one is missed.  This is the underlying reason why in the Linux kernel the goto-based error recovery pattern is used (especially when any kind of locking is involved; multiple concurrent locks are notoriously easy to mess up) instead of duplicating the cleanup cases: the duplicates way too often fall out of sync during maintenance.

Religiously avoiding goto is at least as stupid as using it when it is not necessary.   Don't trust any rule of thumb so far as to claim it always applies; they never do.

The other pattern to avoid goto is to use a separate state variable.  I've shown an example of that in the thread Picuino linked to, related to selective cleanup.  Because this pattern tracks the cleanup needs using a separate variable, it has its own cognitive cost for us humans, and may not always be superior to a well-done goto pattern.

When I asked for an example where goto is truly necessary, I expected someone to bring up a case with a complex, tangled algorithm where execution needs to break out of deeply nested loops in an unexpected way. However, as I mentioned earlier, this is not a justification for why goto is necessary. On the contrary, it’s an indication that there are serious structural problems in your code flow. In such cases, the right approach is not to use goto, but to refactor your code - decomposing it properly, separating resource allocation/deallocation from the core algorithmic logic, and structuring it in a way that eliminates the risk of improper cleanup.

That being said, properly refactoring code is not always easy. It can require significant experience to write simple, clean, and maintainable code. But that doesn’t mean goto is justified - it just means refactoring takes effort.

Regarding the use of goto in the Linux kernel: some projects indeed have less strict policies and tolerate such patterns as long as they are not abused. After all, if the Linux kernel crashes, it's usually not catastrophic - it’s an inconvenience that leads to bug reports, but it doesn't necessarily cause severe harm. However, there are projects where the policies are far stricter and strictly regulated. In such environments, not only are these kinds of mistakes unacceptable, but measures are actively taken to prevent situations where they could even occur. Different projects have different levels of tolerance for bad practices. If a bug on a web page is barely noticed and a Linux kernel crash is just an annoyance, there are also projects where mistakes can cost lives or have severe consequences.

This is why in some projects, shitty-code is not restricted at all, in others it is tolerated within limits, and in some, it is absolutely unacceptable.

Ultimately, no one can forbid you from using goto in your projects. However, it is important to understand that by doing so, you are introducing poor quality shitty-code, and you should be aware of the potential consequences that may arise from it.
« Last Edit: March 31, 2025, 06:10:52 pm by radiolistener »
 

Offline Picuino

  • Super Contributor
  • ***
  • Posts: 1461
  • Country: es
    • Picuino
Re: Converting assembly to C
« Reply #55 on: March 31, 2025, 06:45:37 pm »
Redundancy and monitoring are often used in projects that require so much security.

4 computers in the Shuttle: https://www.nasa.gov/history/sts1/pages/computer.html

Quote
On the Shuttle, four identical AP-101Bs would function simultaneously as a quadruple-redundant set during critical mission phases such as ascent and reentry, processing the same information, derived from completely separate data buses, in precise synchronization. If a conflict arose among the four primary computers, the majority§ would rule, voting the conflicting unit out of the loop. None of the computers, singly or en masse, could turn off any other—that step was left to the crew. An errant machine would announce itself to the crew with warning lights, audio signals, and display-screen messages—all suggesting that the crew might want to isolate (i.e.; turn off) the offending computer from the system.

EDIT:
There are also examples of Linux used in safety-critical environments: https://elisa.tech/
« Last Edit: March 31, 2025, 06:49:47 pm by Picuino »
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Converting assembly to C
« Reply #56 on: March 31, 2025, 07:00:06 pm »
Ultimately, no one can forbid you from using goto in your projects. However, it is important to understand that by doing so, you are introducing poor quality shitty-code, and you should be aware of the potential consequences that may arise from it.
:-DD No, that's just your misunderstanding, confusing bad uses of a tool for the tool itself, and therefore labeling the tool bad.  Your viewpoint is utterly simplistic, and therefore ridiculous.

If you knew anything about maintainable code or avoiding bugs, you'd know that the Linux kernel has much lower bug density compared to any enterprise code.  Your own company, even if producing code used for critical life-sustaining equipment, almost certainly has a higher bug density; the only way you're not mired in lawsuits is a strict review and testing cycle (or clients that just don't notice or know any better).  Labeling certain tools as "shitty" and "poor quality" is just their way of trying to wrangle lower-quality developers like yourself into producing something that can be shipped after sufficiently rigorous testing and review.

No matter how much you repeat it and try to convince yourself and others of it, goto does not automatically make for shitty code.  In the error-case cleanup paths, it is superior to the case you claimed is better, because it does not duplicate code and lead to maintenance-related bugs (one copy updated, the other not updated, and because they are no longer identical, reviewers not catching the discrepancy).  No matter of labeling it "shitty" makes it worse and yours better, because the real world shows your dogma just doesn't hold.

It seems to me you lack the skill and the experience to discuss these matters, so perhaps you should leave it to those who do.

Redundancy and monitoring are often used in projects that require so much security.
For hardware, not for software.  The units run the same code.
 
The following users thanked this post: tooki, 5U4GB

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 5733
  • Country: Earth
Re: Converting assembly to C
« Reply #57 on: March 31, 2025, 08:12:52 pm »
:-DD No, that's just your misunderstanding, confusing bad uses of a tool for the tool itself, and therefore labeling the tool bad.  Your viewpoint is utterly simplistic, and therefore ridiculous.

If you knew anything about maintainable code or avoiding bugs, you'd know that the Linux kernel has much lower bug density compared to any enterprise code.  Your own company, even if producing code used for critical life-sustaining equipment, almost certainly has a higher bug density; the only way you're not mired in lawsuits is a strict review and testing cycle (or clients that just don't notice or know any better).  Labeling certain tools as "shitty" and "poor quality" is just their way of trying to wrangle lower-quality developers like yourself into producing something that can be shipped after sufficiently rigorous testing and review.

Having worked on medical device projects that undergo regular testing and audits, I can confidently say that, compared to the level of rigor I have observed in such environments, the Linux kernel is a mess of poorly structured code with numerous bugs. However, this is not to say that Linux is inherently bad or mismanaged - I fully recognize that it is a free, community-driven project that lacks the level of funding necessary to enforce strict development practices. In fact, considering these constraints, I’d say it is holding up remarkably well, and I genuinely appreciate its development. That said, comparing it to large-scale commercial projects with significantly stricter methodologies and regulatory requirements would simply be incorrect.

Therefore, I find it quite surprising to hear you claim that Linux has fewer bugs, when my own experience shows the exact opposite. Your response makes it quite evident that you have never worked on projects with strict regulatory requirements, where coding standards are significantly more rigorous than in typical software companies.

Comparing bug density in the Linux kernel to enterprise software is meaningless without context. The Linux kernel is developed under an open-source model with thousands of contributors, strict code reviews, and an extensive testing process - yet even then, issues still arise. In contrast, projects in regulated industries, such as aviation, medical, or automotive safety systems, operate under even stricter constraints, where certain coding practices - including the use of goto - are outright prohibited due to their potential to introduce hard-to-trace errors.

Dismissing coding guidelines as mere attempts to "wrangle lower-quality developers" only shows a lack of understanding of how high-assurance software is built. In environments where failures can cost lives, health or big money, best practices exist for a reason - namely, to minimize risk and enforce maintainability at a level that goes far beyond what is acceptable in general-purpose software.

No matter how much you repeat it and try to convince yourself and others of it, goto does not automatically make for shitty code.  In the error-case cleanup paths, it is superior to the case you claimed is better, because it does not duplicate code and lead to maintenance-related bugs (one copy updated, the other not updated, and because they are no longer identical, reviewers not catching the discrepancy).  No matter of labeling it "shitty" makes it worse and yours better, because the real world shows your dogma just doesn't hold.

I completely disagree with your claim that goto ensures "superior" resource cleanup ways and eliminates errors related to incorrect exits from nested loops or improper resource deallocation. On the contrary, using goto makes such mistakes possible and, worse, hidden during compilation and code review.

A compiler will never be able to detect that you skipped an essential cleanup block that should have been executed during an early exit from an inner loop - because goto does not enforce any constraints in this regard. And a person reviewing your code might simply overlook the issue due to the spaghetti-like structure that goto introduces.

Simply put, goto allows you to jump almost anywhere, and the compiler won’t flag it as an issue. This lack of proper checking is the real problem.

This is precisely why using goto does automatically turn your code into shitty code - not because someone keeps repeating it or personally believes so, but because it objectively makes errors harder to detect and trace at both the compilation and review stages. Furthermore, in the event of a critical incident caused by software failure, analyzing and identifying the root cause becomes significantly more difficult when control flow is obscured by goto statements. Investigations in high-stakes environments, such as medical devices or safety-critical systems, require clear, predictable execution paths to efficiently diagnose and address failures. Code that relies on goto introduces unnecessary complexity, making such investigations more time-consuming and error-prone, which is simply unacceptable in industries where failures can have severe real-world consequences.

A straightforward example can be seen in the code provided by the topic starter, which is riddled with labels and goto statements to the point that even its own author struggles to understand it. I have had to analyze similar code in the past to determine its behavior, and while I could reconstruct its logic and rewrite it in a structured manner, the reality is that such code is shitty code - difficult to work with, requiring excessive time and effort for analysis. It’s tedious, error-prone, and unnecessarily complex, which is exactly why I have no desire to deal with it.

If you believe that goto somehow makes code more reliable, I encourage you to try to rewrite his code yourself. You’ll quickly realize firsthand why I categorize it as shitty code.  ;)

It seems to me you lack the skill and the experience to discuss these matters, so perhaps you should leave it to those who do.

Your assumption is incorrect. I have spent more than decade working on medical device projects, where strict regulations, rigorous audits, and high safety standards are mandatory. In such environments, code quality is not a matter of personal preference but a strict requirement - far beyond what is typically enforced in general software development.

Given this experience, I find it quite ironic that you suggest I lack the skill or expertise to discuss these matters. If anything, your repeated reliance on goto as a "solution" to resource management issues suggests a lack of familiarity with structured programming principles and best practices in high-reliability systems. Perhaps instead of dismissing opposing viewpoints, you should consider that there are industries where your approach would not meet the necessary standards for safety, maintainability and regulatory requirements.


If you don't believe me, you can read other sources, for example you can read this article:
https://web.eecs.umich.edu/~imarkov/10rules.pdf

Especially the first rule in the list:
Quote
Rule 1: Restrict all code to very simple control flow constructs - do not use goto statements, setjmp or longjmp
constructs, or direct or indirect recursion.
« Last Edit: March 31, 2025, 08:57:15 pm by radiolistener »
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Converting assembly to C
« Reply #58 on: March 31, 2025, 10:04:29 pm »
Having worked on medical device projects that undergo regular testing and audits
Maybe as an intern, perhaps.  Other than that, I think you're full of shit, with nothing to back up your claims, except parroting "rules" you've heard from others.
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 5733
  • Country: Earth
Re: Converting assembly to C
« Reply #59 on: March 31, 2025, 10:37:35 pm »
Maybe as an intern, perhaps.

I understand that you might question my experience, but just to clarify, I joined my first company working with medical devices as a mid-level developer and grow to Senior Software Engineer. Prior to that, I worked as a Lead Developer in a company focused on industrial smart sensors for pressure, temperature, and gas metering devices used in large gas pipelines. I developed firmware for industrial sensors and meters, which could be seen as an equivalent to Honeywell products, although the company was local. I independently developed the firmware from scratch, including conducting tests, research, and selecting algorithms for temperature compensation, calibration, and more. I also participated in the certification of finished devices and the deployment of the first units at the company’s facilities. The firmware ran on MSP430 (MSP430F149 if I remember correctly) under an RTOS kernel, which I ported by himself to the MSP430 platform. Almost all of the firmware code was written by me from scratch. Some of the temperature compensation algorithms were suggested to me by an acquaintance who had worked on pressure sensors designed for high-temperature conditions (>700°C). I simplified and refined these algorithms. The calibration algorithms were recommended by someone who had previously worked in the production of Soviet nuclear missiles. According to his stories, he had worked on inertial navigation systems development. He also shared tales about how the KGB would arrive for product acceptance inspections, and based on his accounts, there were areas even back then where the engineering standards were exceptionally strict. :)

Back then, I had to do more than just write code - I spent days next to a thermal chamber with a pressure compressor, recording sensor characteristics under various temperature and pressure conditions and then analyzing the data. I was also involved in the development of the measurement circuitry, specifically the ADC-related aspects. However, the primary circuit design was handled by another engineer; I mainly suggested different ADC configurations, which he then prototyped, and we tested them together. The main challenge in measurement was achieving high accuracy across a wide temperature range from -60 to +80 degrees Celsius. Sensor readings were highly temperature-dependent, with the pressure sensor being particularly sensitive to temperature variations.

Later, I transitioned to another medical devices company directly as a Senior Software Engineer. Additionally, if you are interested in my experience with C, I started learning it in school before attending university, at about 12 years old (first on HI-SOFT C on ZX Spectrum and later on IBM PC). In fact, even before university, I wrote my own UI in C++ for an EEPROM programmer using the Borland Turbo Vision library. I started learning Basic and Z80 assembly around the age of 10 (it was on ZX Spectrum). My interest in electronics began around the age of 7, and by 8, I had already soldered my first radio receiver. :)

One of the medical devices companies I worked for is in the top 10 of the Fortune 500 list. The second is a less well-known US company, but its medical electronic equipment is also quite widespread worldwide. The third company is also a relatively lesser-known US firm, but it has offices and operates globally, including in the US, EU, Israel, and many other countries. It is well-known in the medical field and among healthcare manufacturers, although its name may not be familiar to the general public.

In all medical device companies I worked for, my position was Senior Software Engineer. I am not an intern. Interns are typically hired from a pool of less experienced individuals with a commitment to work exclusively for the company. Instead, I am the type of engineer hired to lead and contribute to new projects, to kick-start new initiatives, or to rescue projects that are struggling due to an overabundance of internal personnel. Interns are usually not capable of handling such responsibilities, if that is what you meant by referring to interns.

May I ask about your experience? I'm curious to know what background you bring to the discussion?

Other than that, I think you're full of shit, with nothing to back up your claims, except parroting "rules" you've heard from others.

I understand that you disagree with my points, but resorting to personal insults isn't productive or helpful to the discussion. Perhaps there is a generational gap between us that is causing a difference in perspective, but I don't believe that young approach of insulting others adds any value to the conversation or reflects well on you. I would prefer to continue our discussion in a more constructive and respectful manner.


My point of view has already been confirmed by the original poster, who provided an example of code using goto. As you can see it almost non-readable. Additionally, despite several attempts to provide examples where goto allegedly seems necessary, I presented equivalent code examples that do not require goto. I also provided an example of guidelines from NASA, which state the same - avoid using goto. Don't you think that the evidence supporting my position is more than sufficient, and that you're simply choosing to disregard it?

In my view, this is sufficient evidence. What further proof would you require to back up my claims?

Indeed, every company has its own set of rules and regulations, and as professionals, we are obligated to adhere to them. In more serious organizations, these rules can be quite strict, but I don't see anything wrong with that. These guidelines are established to ensure the production of high-quality code, and they are based on experience rather than arbitrary decisions. They are developed through careful analysis and real-world experience, and following them is essential for maintaining standards and consistency. Over time, as you gain more experience, you’ll realize that these rules are not there to hinder you, but rather to guide you toward writing better, more reliable code.
« Last Edit: April 01, 2025, 02:03:59 am by radiolistener »
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 5733
  • Country: Earth
Re: Converting assembly to C
« Reply #60 on: April 01, 2025, 02:24:45 am »
@Nominal Animal, You remind me of another user on this forum who tried to convince me that he was a seasoned professional with extensive experience, while claiming that I didn't understand anything and that I'm talking complete bullshit. The irony was that he portrayed himself as an expert on a program I had actually written, yet he was unaware of that fact. It was quite amusing. :D

Subsequently, I came across other messages from that user, and I was rather disappointed to find that he had a poor understanding of the topic and lacked even basic knowledge. Yet, for some reason, he resorted to insulting me. Given that, as I remember, you are well-versed in digital filters (isn't it?), it's somewhat surprising to see a similar approach with insults coming from you.
 

Offline 5U4GB

  • Super Contributor
  • ***
  • Posts: 1729
  • Country: au
Re: Converting assembly to C
« Reply #61 on: April 01, 2025, 08:19:35 am »
In structured programming you can ALWAYS replace goto with other operations.

"The fact that it is possible to push a pea up a mountain with your nose does not mean that this is a sensible way of getting it there" - Chris Strachey.
 
The following users thanked this post: Picuino

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Converting assembly to C
« Reply #62 on: April 01, 2025, 09:34:12 am »
In structured programming you can ALWAYS replace goto with other operations.

"The fact that it is possible to push a pea up a mountain with your nose does not mean that this is a sensible way of getting it there" - Chris Strachey.

I prefer "It is possible to cross the Alps on a bicycle, but that doesn't mean it is a sensible way of travelling" :)
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline 5U4GB

  • Super Contributor
  • ***
  • Posts: 1729
  • Country: au
Re: Converting assembly to C
« Reply #63 on: April 01, 2025, 11:13:45 am »
I prefer "It is possible to cross the Alps on a bicycle, but that doesn't mean it is a sensible way of travelling" :)

Drifting a bit off topic but my dad did actually cross the Alps on a bicycle (meaning cycled on roads through the Alps, not up and down mountainsides) as part of some enthusiastic youth sporting nature thing.  He apparently quite enjoyed it.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Converting assembly to C
« Reply #64 on: April 01, 2025, 11:22:04 am »
I prefer "It is possible to cross the Alps on a bicycle, but that doesn't mean it is a sensible way of travelling" :)

Drifting a bit off topic but my dad did actually cross the Alps on a bicycle (meaning cycled on roads through the Alps, not up and down mountainsides) as part of some enthusiastic youth sporting nature thing.  He apparently quite enjoyed it.

I've walked across parts of the Dolomites, including the old commercial "Bread Trail", i.e. the Viel Di Pan. Definitely a "fit for purpose" transportation mode, since the purpose was "memorable fun challenging holiday".
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: newbrain

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5093
  • Country: gb
Re: Converting assembly to C
« Reply #65 on: April 01, 2025, 11:51:12 am »


There is a nice book about this kind of adventure
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5093
  • Country: gb
Re: Converting assembly to C
« Reply #66 on: April 01, 2025, 12:31:33 pm »
Religiously avoiding goto is at least as stupid as using it when it is not necessary.
Don't trust any rule of thumb so far as to claim it always applies; they never do.

The DO178B level A-D integrated with avionics rules strictly prohibits any use of "goto" for everything except "critical sections", which are - by definition - considered "low level", therfore all documents and testing methods require special activities, which are known, well tested; the point is that, being special, they require many more hours both from the testing team and from the QA team, and this for each iteration between development and testing, therefore for each revision.

It is therefore a question of "how much does it cost" to have a "goto", rather than replacing it with something else, which does NOT require special procedures.

There are always Critical sessions in RT operating systems(1), so having a goto in those sessions does not add much more cost.

But if you put "gotos", say ... in the application layers (where it should be avoided), then you need to provide a special testing activity just for that goto.

So, it can also be seen as a question of costs :-//

edit:
(1) e.g. WxWorks-RT is certified for DO178B-levelA, it can be used in supersonic aircraft traveling >= 1,193.76 km/h.
It uses "goto" in a few critical sections. Only a few sections, but testing and QA of these special sections requires "4 times +1" more effort from both the testing team (x2 effort) and QA team(x2 effort) than the rest, plus manual inspection and approval from seniors(+1 effort).
« Last Edit: April 01, 2025, 01:00:44 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17781
  • Country: fr
Re: Converting assembly to C
« Reply #67 on: April 01, 2025, 02:23:49 pm »
In MISRA-C, the use of goto is not prohibited entirely, but must be restricted to only one exit point in a given construct (function or loop). And it's not just with 'goto', but also with 'break'.
So, in a loop, you can only use a single break. The idea is to have a single point of exit inside a loop, apart from its normal condition.
Which already allows two different termination conditions. With some stricter rules, a single termination condition is required.

Sometimes those rules can be clunky to respect, but they are not stupid either. Invariants are much easier to verify if you don't have tons of conditional exits all over the place.

But clunky this can be. Say, you have a sequence of statements that can return an error. Enforcing a single point of exit in this case it very inconvenient, at least with usual languages.
 
The following users thanked this post: 5U4GB

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Converting assembly to C
« Reply #68 on: April 01, 2025, 04:01:37 pm »
The DO178B level A-D integrated with avionics rules strictly prohibits any use of "goto" for everything except "critical sections", which are - by definition - considered "low level", therfore all documents and testing methods require special activities, which are known, well tested; the point is that, being special, they require many more hours both from the testing team and from the QA team, and this for each iteration between development and testing, therefore for each revision.
Exactly.  These rules in DO178B and MISRA-C do not magically cause bugs to not occur; they simply make it easier to catch problems in testing and QA review.

Simply put, the subset of C these safety standards specify is not "bug-free" or the non-"crappy" parts of C; it is the subset that existing tools and procedures can review and verify effectively.  They are all about the process of safety-critical product development, using less than perfect developers (i.e. humans).

For minimal bug density C code, go take a look at Dan J. Bernstein's projects.

(1) e.g. WxWorks-RT is certified for DO178B-levelA, it can be used in supersonic aircraft traveling >= 1,193.76 km/h.
It uses "goto" in a few critical sections. Only a few sections, but testing and QA of these special sections requires "4 times +1" more effort from both the testing team (x2 effort) and QA team(x2 effort) than the rest, plus manual inspection and approval from seniors(+1 effort).
Exactly.  A very good example of how goto is an useful tool if carefully and selectively applied.  The problem is not in goto itself, but in how most developers use it, leading to a "rule of thumb" saying that "using goto is always bad".

Based on a quick grep over my test case archive, I use goto in fewer than one project in hundred.  (I didn't bother to check how often in those rare cases I use computed gotos, a GNU extension, though; it can make certain complex state machine structures much simpler to maintain without introducing new bugs.)

Sometimes those rules can be clunky to respect, but they are not stupid either. Invariants are much easier to verify if you don't have tons of conditional exits all over the place.
Sure; but, it is important for anyone developing safety-critical systems to understand that these rules are about the development process, to be utilized when you do have the test and review QA procedures in place; they do not magically make for better code.

It is perfectly exemplified by the fact that both MISRA-C and DO178B have exception clauses and procedures set for when the simplified subset of C just isn't the appropriate tool.  They do not say "goto always leads to buggy code", they say "use goto and other constructs sparingly, because they make the required testing and QA more difficult".

I would go even further –– and DiTBho can comment on this, because they developed their myC variant of C for these purposes exactly –– and claim that even if you write MISRA-C or DO178B -compliant C from the get go, it does not really reduce the number of bugs and issues in the code; it only makes testing and QA review easier.  That is, if you do not do the testing and review cycles, and simply trust that being MISRA-C or DO178B compliant makes for better code and fewer bugs, you will be sorely disappointed.

That is also the reason why Ada/Spark is often used for safety-critical code: it is designed to allow automated correctness verification (logical soundness, verifiability, bounded resource use).  It is slightly harder to reach the same performance as C, but much more of the review and verification process can be automated.

I just cannot understand how anyone non-stupid could extrapolate "goto is always bad and must not be used" from all of this.
 
The following users thanked this post: 5U4GB

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5093
  • Country: gb
Re: Converting assembly to C
« Reply #69 on: April 01, 2025, 04:28:31 pm »
I would go even further –– and DiTBho can comment on this, because they developed their myC variant of C for these purposes exactly –– and claim that even if you write MISRA-C or DO178B -compliant C from the get go, it does not really reduce the number of bugs and issues in the code; it only makes testing and QA review easier.  That is, if you do not do the testing and review cycles, and simply trust that being MISRA-C or DO178B compliant makes for better code and fewer bugs, you will be sorely disappointed.

Yup, precisely, it only makes testing and QA review easier.

It must also be said that for each activity a lot of documents must be prepared, many of which involve testing activities, both manual and automatic.
Automatic activities are faster and less "boring" than manual ones, and require less effort, but they require greater "observability" of the code.
So it is good, also for this reason, to write the code in a certain way, to simplify your life later in the testing activities, and to simplify the life later in QA activities.



The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: Nominal Animal

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Converting assembly to C
« Reply #70 on: April 01, 2025, 06:00:29 pm »
To be very clear: I fully agree that following MISRA-C or DO178B will result in a better end product.  I am only saying that labeling certain features like goto to always lead to crappy code is absolutely untrue; as is following a subset of MISRA-C or DO178B process and believing the end result is "almost" as good as if one were to follow the full process as outlined in said standards.

Those standards are not about picking only the best in the programming language; they are about the entire process, and using a subset of the programming language that allows the most efficient and process-friendly subset of said language.

There is a big difference in the process of developing safety-critical code, and in writing robust, reliable, minimally-buggy code.  Neither involves labeling some C language features as always leading to crappy buggy code; they are both all –– and only! –– about a proper engineering approach to software development.  You just cannot distill that into always-correct rules of thumb or dogmatic avoidance of language features.  I'm not saying to use goto whenever you feel like it, either: I use it exceedingly rarely, because I only use it whenever it is appropriate.

Offhand, I know of only one language feature that always leads to crap, and that was the Magic Quotes feature in PHP.  And even that was more like a interpreter configuration than language feature.  It was an early doomed attempt at making it easier for newbies to write "safe" PHP, by automagically escaping non-SQL-safe characters received from HTML forms.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 11173
  • Country: fi
Re: Converting assembly to C
« Reply #71 on: April 01, 2025, 06:32:40 pm »
To be very clear: I fully agree that following MISRA-C or DO178B will result in a better end product.

I really don't.

If you just follow them because it gives you a feeling of quality, without thinking about any quality assurance process, all bets are off. Some of the rules are slightly good; others (like full ban of goto or function pointers) potentially make for slightly worse (less maintainable, less readable, so more prone to bugs) code in some cases, but not always, and not for every developer - these rules could also prevent abuse of said constructs.

Knowing you are writing "MISRA code" could also drive you to false sense of security, a well known phenomenon, then again it's also an overdiagnosed phenomenon by kitchen sink failure analysts, so really, dunno :-//

Typical example of this would be a company like ST, known from producing totally random crap software, suddenly making a statement that their code is MISRA compliant. Of course it's still as buggy as ever, with zero documentation and absolutely zero consistency and zero design, just something ad hoc summer trainee crap held together with bubble gum. In a process like this, there is a real risk that new bugs are added when the new summer trainee is hired to modify all code to be "MISRA compliant" for pure marketing purposes. But I don't know how common this is. Maybe I'm exaggerating the risk.

And then again, if you do implement rigorous quality processes, like (hopefully) any company operating in aviation... I'm 100% certain your product quality would be top-notch even if you didn't use MISRA.

So I believe things like MISRA make only very small difference in the big picture, if any. Probably bigger quality gains can be had by having programmers read the rules carefully and think about them, even if they are not forced to follow them strictly.

But the real aim for MISRA & co is clear. You said it already but I'm going to repeat it: it is obviously easier to analyze code flow automatically and manually, when number and types of code flow affecting constructs is limited (goto, function pointers). The critical question however is, what does it do on the big picture? That function pointer was (hopefully) introduced by a developer to reduce repetition, copy-pasting, or complicated if-else conditional mess. Copy-pasted repeated if-else mess might be easier to analyze for a machine, so if you compare the implementation against a machine-readable specification to do formal verification, then that's a win. But is this relevant for most projects people think about? If you just introduce MISRA and think that this now gives you aviation quality code, without introducing the formal verification that needs to go with it, you just introduced new sources of bugs from ignoring patterns like DRY, well known to improve quality outside of fields like aviation.

 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Converting assembly to C
« Reply #72 on: April 01, 2025, 08:06:57 pm »
To be very clear: I fully agree that following MISRA-C or DO178B will result in a better end product.
If you just follow them because it gives you a feeling of quality, without thinking about any quality assurance process, all bets are off.
Absolutely –– but I meant that if you follow them fully, including the review and QA processes –– then the end result will be better.  They specify the product development process, not a subset of C to use to get better results.

Taking just a small part, say the subset of C these standards define, gets you absolutely nowhere (except for delusions).  These standards are about the entire process: a framework you work in, not a set of useful ideas you can pick and choose and be good.

So I believe things like MISRA make only very small difference in the big picture, if any.
For individual programmers working alone, they give very little, unless you delve very deep into the very process like DiTBho described wrt. DO178B and "myC", and emphasizing the documentation and review steps needed to actually fulfill the ideas behind those standards.  If I've understood correctly, the entire "myC" idea was to subset-and-extend C to better fit the entire process, specifically debug/review/verification.  (Do firmly point it out if I've misunderstood its purpose, DiTBho!)

Neither MISRA-C nor DO178B should be considered a "programming language standard" at all.  They are about the full development process, with the subset of C chosen to fit that process.  They don't work when you work alone; they're organizational process standards.

I claim that statements like ST declaring their code to be "MISRA-C compatible" is just marketing wank, and means basically nothing.  It is like declaring oneself to be vegan, because the meat one consumes is all from herbivorous animals.  It is picking one detail, and pretending it is the main point in an effort to try and mislead others.  For an organization, it means they'll still have to do the entire testing-review-QA cycle –– and knowing ST's code quality as shown online, will have to rewrite most of it to actually pass and satisfy the present needs.

If you just introduce MISRA and think that this now gives you aviation quality code, without introducing the formal verification that needs to go with it, you just introduced new sources of bugs from ignoring patterns like DRY, well known to improve quality outside of fields like aviation.
Yes, exactly.  Or, conversely, that limiting oneself to the subset defined in MISRA-C or DO178B somehow magically makes oneself produce better code.

The methodology or approach to write better code in the first place is usually called software engineering, because you apply the same engineering principles to software development as you do when designing larger systems with lots of components.



To circle back to the topic at hand, converting machine code or assembly to C, the simple answer is that you don't.

What you do, is convert the machine code to any intermediate form or programming language that makes it easier for you to decipher its operation and the intent of the original developer(s).  You write a detailed description of it, either formally (recommended if group effort) or commenting the intermediate language (only valid if doing this alone or with a coding buddy).  Ghidra and other tools can be quite useful here.

I like to follow that up by creating a limited simulated environment where I can implement parts/subsystems in my preferred programming language, and compare its outputs to the original outputs from the same inputs.  I do this for individual modules.  After I have sufficient modules, I start looking at their interactions, and trying to understand how the developer approached the overall problem.

When you have verified you have a full understanding of the operation of the system at hand, you reimplement it.  You don't convert the code; you write new code that fulfills the same requirements.  You use the old code to inform you of the possible approaches, but as long as you note all the side effects and interactions, you don't need to do it the exact same way; it suffices that all intentional side effects and results match.

For myself, I don't mind if the intermediate form of the new code contains gotos, because I know from experience that when the rewrite/reimplementation behaves like the original, I'll still want to refactor the key parts of the code to be maintainable.  I do not have the brainpower to think about long-term maintenance when I first rewrite code from one language to another; I need to sleep in between to see the code with fresh eyes and shift focus.  It is at least 99% likely that I'd replace those goto structures with subfunctions, switch statements, do..while or while "loops", et cetera.

Splitting even this process into sub-steps makes it much more manageable.  Even by rereading this thread we can see that starting with an intermediate representation of the machine code (including clunky constructs like gotos and labels scattered everywhere), and then rewriting these using easier to maintain patterns, is the way to go.  However, do not forget that you will forget the intention/purpose of each function and chunk of code in a few weeks.  You will definitely want to write comments or descriptions of your understanding of the purpose or developer intent of each function.  What the functions do is easy to see in the code, but that intent is what makes it possible to consider whether what the code does is correct or not.  If you don't have or remember that intent, you'll have to try and rediscover it, as otherwise you can only fix obvious typos (like off by one errors), and not any misunderstandings of what the purpose of the intent of the original code was.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17781
  • Country: fr
Re: Converting assembly to C
« Reply #73 on: April 01, 2025, 08:41:11 pm »
I'd say about half of the rules in those guidelines is "common sense" and relatively sane and the other half is extreme to various degrees and indeed made to accomodate large teams of developers while ensuring a reasonably common code style and avoiding constructs and language features that are known to be "slippery", making the code easier to review and easier to test.

Of course that doesn't mean the output will be automatically of good quality, and sure enough, it can be misused and lead to the problem of "programming to just pass the automatic static analysis checks" (which indeed I suspect is what ST devs mostly do).

Certainly far from ideal, but OTOH managing software projects, when any kind of reliability and safety is involved, is extremely difficult, in particular when your team exceeds about 2 developers. So, yeah.
 
The following users thanked this post: Nominal Animal

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5093
  • Country: gb
Re: Converting assembly to C
« Reply #74 on: April 01, 2025, 09:09:19 pm »
like DiTBho described wrt. DO178B and "myC", and emphasizing the documentation and review steps needed to actually fulfill the ideas behind those standards.  If I've understood correctly, the entire "myC" idea was to subset-and-extend C to better fit the entire process, specifically debug/review/verification.

That's correct, I think this is just one of the attempts made, but this is the direction that seems to provide significant help.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: Nominal Animal


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf