C/C++ [C++] Never have more than 1 return statement?

  • Thread starter Thread starter Jamin2112
  • Start date Start date
AI Thread Summary
The discussion centers on the debate over whether a function in C++ should have only one return statement. Some argue that having multiple return points can enhance readability and simplify code, especially in cases involving preconditions or error handling. Others advocate for a single exit point to improve debugging and maintainability, citing traditional coding standards and practices. The conversation highlights the tension between modern coding practices and older rules, with some participants suggesting that the single return point rule is outdated. Ultimately, the effectiveness of return statements depends on the context and complexity of the function being written.
  • #51
gmar said:
I don't see how those opinions differ.
I do. Green Hills was and to some extent remains the dominant supplier for this type of hard real-time, safety-critical software. Allowing exceptions would have precluded Green Hills. That was not a decision to be made lightly.

The hard real-time, safety-critical military software community had just recently made the switch from Ada to C++. It was the Ada exception model was the primary inspiration for the C++ exception model. The dim view that Green Hills took toward Ada exceptions was also the primary inspiration for their not liking C++ exceptions. The dominant supplier of hard real-time, safety critical Ada development platforms prior to C++? It was Green Hills. It's no surprise that this real-time, safety-critical military software community banned the use of C++ exceptions. They had already banned their use in Ada!

Perception and FUD had a lot to do with this decision. The vendors who truly did support C++, as opposed to C with Classes, which is what the EC++ subset really should be called, were new kids on the block and not quite trusted. Green Hills had been working in this domain for a long time.


I guess that commerically, C++ did "need" some kind of high-profile embedded project.
The hard real-time safety-critical military software community needed a language that encouraged safe programming practices, and by 1997 it was becoming apparently that this language was not Ada. Ada programmers were just too few in number, tool support was minimal because Ada remained a cottage industry language as opposed to a commodity language. That language wasn't C. Heaven forbid! The mindset of those who like bondage and discipline languages such as Ada balk at languages such as C. Ada was invented partly in response to the growth of languages such as C. C++ on the other hand has a lot of safe language features of Ada; these were once again inspired by Ada. C++ had two key things Ada lacked: A good amount of commercial support and a growing programmer base. C++, not C, was a natural fit.


If non-trivial code isn't formatted according some kind of formal standard, it is broken.
That's your opinion. How far do those standards go? Down to spacing before equals signs in an assignment statement? That to me is ludicrous. It's the IDE that's broken here, not the code.

My opinion of IDEs? I am not a fan. They're at what I call the six month old puppy stage, and they will remain at that stage until the hard AI problem is solved. The "six month old puppy stage" -- When you buy a brand new puppy, you *know* it's going to pee on the floor. It's guaranteed, and you'd better be prepared for that inevitability. You don't beat the puppy. You beat yourself for not being prepared. When she becomes an older dog? She'll hold her bladder until it bursts rather than pee on the floor if you go out for supper and she happens drinks too much water while you're gone (or even if you were a doofus and didn't let her out before you went). On the other hand, a six month old puppy will have learned that you absolutely do not approve of peed-on carpets, but sometimes she'll just forget.
 
Technology news on Phys.org
  • #52
In the past 3.5 weeks, I have written 4116 lines of code. That count doesn't include blank lines, comment line, or lines that have nothing more than an open or close squiggly brace.

Actually, in the process of writing those lines, I have probably written many hundred more - and then deleted them again as I rewrote and rearranged the code to avoid having the same basic function repeated. That's one of my rules - avoid cut and paste code, avoid duplicate functions. They are the real maintenance issues.

While I am working the code - there is no room for anything other than what I want the code to look like. I don't choose an arbitrary style, I choose a style that will let me find things in seconds. This may or may not be a style that a reviewer or someone else finds appealing - but that's a different project.

If I am looking to make non-trivial changes to the code, I do not worry about how much a code reviewer is going to have to look at. In fact, by the time I am finished, there may be twice as many modules all with different file names from what was there to start with.

And, on the topic of "trivial changes", you have to be careful. Before making any change - you need to scope out its general effects. In most cases, the change you're making is not one that was anticipated, so you need to own the code and really understand what is relying on what.

If you put up standards that interfere with the coding process itself - you are going to loose.

I am unsympathetic to the issues of reviewing code that's been reformatted. I've done such reviews. The changes are not difficult to identify. Aside from ignoring white-space changes on a line (which MS Sourcesafe can do), you can also reformat both the before and after to the same pattern and compare them.

There are much more important things to look for in a code review than style.
 
  • #53
There's an underlying issue here that I think people are on different sides of and perhaps not realising.

This is, "Do you believe that your coding standard is part of your project's specification?"

If you do, it's easier to come to the decision to reject non-compliant code. Especially in the newer design methodologies where developers have input into the specification. For example Scrum, where feature requests ("user stories") can come from developers as well as the end-user.

If you don't, it's a lot harder. For the people in the don't camp, do you consider the choice of language to be part of the specification? Some projects require the use of language X. Why is this rule considered more concrete than specifying ways in which said language can be used?

Really the discussion about specific requirements (spaces before equals) are symptom of the greater issue, which is the one above.
 
Last edited:
  • #54
gmar said:
There's an underlying issue here that I think people are on different sides of and perhaps not realising.

This is, "Do you believe that your coding standard is part of your project's specification?"
You are making an implicit assumption here of a very rigid, very authoritarian, very complete, and machine testable coding standard. I've seen such standards, and I never liked a single one of them.

Your opinion and mine are at odds. You apparently like the widely varying opinions on how to best write code to be codified as rules that dictate which opinion is the one and only right opinion. I don't see that, personally. When I'm in charge (sometimes I'm a peon, sometimes I'm in charge), I make sure the coding standards are not rigid. That this means the standards aren't fully testable / fully automatable doesn't bother me.

I'm a big fan of Sutter's and Alexandrescu's rule #0: Don't sweat the small stuff. Standards that say exactly how to indent, exactly how to use whitespace, that one should use if (0 == variable) rather than if (variable == 0) -- that to me is sweating the small stuff.
 
  • #55
If you violate this rule you must be careful that you are not skipping things that you routinely put at the end of a subroutine (incrementing counters, changing pointers, freeing memory, etc.). I violate this rule to skip cases that do not apply in the function, but I occasionally pay the price. In safety critical code, you have to take a hard look at any violations.
 
  • #56
What rule? Yes, the single point of entry / single point of return is a common rule in C, particularly in low level systems programming. It is not a widely accepted rule in C++. If anything, it is oftentimes viewed as an anti-pattern in C++. As gmar wrote in post 39, "One community's pattern is another community's anti-pattern."

There is an overarching concept here that applies to all languages, related to three key questions:
- Does the function clean up after itself?
- What happens if things go wrong?
- What guarantees does the function make?

Done right, the last question encapsulates the answer to the other two. There are a number of different guarantees a function can provide.
  • Good question! Anything might happen if you use this product.
    This is the non-guarantee that most software products demand that the user of the product consent to.
  • I guarantee that bad things will happen if you use the product incorrectly.
    For example, calling sqrt(-1) can make your program go belly up, depending on how you've set the floating point error handling. But since the man page for sqrt documents this behavior, that's OK! It's a feature, not a bug.
  • I guarantee that nothing can possibly go wrong.
    For example, any reasonable implementation of the sine function will be able to make this guarantee. (Note: An implementation that uses Taylor expansion is not "reasonable".)
  • I guarantee that the function clean up after its mess (but it might leave a side-effect or two).
    For example, if you call the C scanf function to parse six integers from a stream but the stream only contains three integers and an EOF, the function will return an error code saying something went wrong. However, those first three integers will typically be parsed and stored. The function obeys the basic guarantee in that no matter what happens, any resources allocated internally are released prior to returning.

    This basic guarantee, "I clean up my mess even if things go wrong", is not easy to achieve. There's a lot more to resources than allocated memory. File handles, internet connections, shared memory, semaphores, mutexes: All of these are resources, many of which encapsulate multiple low-level resources that are invisible to all but system programmers.
  • I guarantee that the function cleans up after its mess and has no side effects unless everything works.
    This is the guarantee that database programmers expect to see. A commit either commits everything that was requested or it leaves the database untouched if something goes wrong. This guarantee is extremely hard and oftentimes very expensive to achieve. Even most kernel code does not make this strong guarantee.
 
Last edited:

Similar threads

Replies
31
Views
3K
Replies
13
Views
2K
Replies
45
Views
5K
Replies
8
Views
4K
Replies
39
Views
4K
Replies
17
Views
2K
Back
Top