15

In C++, features like exceptions impact your whole program: you can either disable them in your whole program, or you need to deal with them throughout your code. As a famous article on C++ Report puts it:

Counter-intuitively, the hard part of coding exceptions is not the explicit throws and catches. The really hard part of using exceptions is to write all the intervening code in such a way that an arbitrary exception can propagate from its throw site to its handler, arriving safely and without damaging other parts of the program along the way.

Since even new throws exceptions, every function needs to provide basic exception safety — unless it only calls functions which guarantee throwing no exception — unless you disable exceptions altogether in your whole project.

Hence, exceptions are a "whole-program" or "whole-team" feature, since they must be understood by everybody in a team using them. But not all C++ features are like that, as far as I know.

A possible example is that if I don't get templates but I do not use them, I will still be able to write correct C++ — or will I not?. I can even call sort on an array of integers and enjoy its amazing speed advantage wrt. C's qsort (because no function pointer is called), without risking bugs — or not? It seems templates are not "whole-team".

Are there other C++ features which impact code not directly using them, and are hence "whole-team"? I am especially interested in features not present in C.

Update: I'm especially looking for features where there's no language-enforced sign you need to be aware of them. The first answer I got mentioned const-correctness, which is also whole-team, hence everybody needs to learn about it; however, AFAICS it will impact you only if you call a function which is marked const, and the compiler will prevent you from calling it on non-const objects, so you get something to google for. With exceptions, you don't even get that; moreover, they're always used as soon as you use new, hence exceptions are more "insidious". Since I can't phrase this as objectively, though, I will appreciate any whole-team feature.

Update 2: instead of C++ feature I should have written something like "C++-specific feature", to exclude things like multithreading which apply to a large amount of mainstream programming languages.

Appendix: Why this question is objective (if you wonder)

C++ is a complex language, so many projects or coding guides try to select "simple" C++ features, and many people try to include or exclude some ones according to mostly subjective criteria. Questions about that get rightfully closed regularly here on SO.

Above, instead, I defined (as precisely as possible) what a "whole-team" language feature is, provide an example (exceptions), together with extensive supporting evidence in the literature about C++, and ask for whole-team features in C++ beyond exceptions.

Whether you should use "whole-team" features, or whether that's a relevant concept, might be subjective — but that only means the importance of this question is subjective, like always.

0

5 Answers 5

11

I would nominate concurrency as a 'whole team' feature.

Although it is possible to design the software such that only a few experts need to be aware of concurrency issues and the rest of the team can reap the benefits without being concerned with the complexities (like you can do with templates), in practice it does not work that way. In practice, if you have multiple threads, then you have to analyse carefully for each and every variable you use if there are potential concurrency issues with that use.

5
  • I agree that threads are such a whole-team features, though they're not C++-specific. However, there are also other interfaces to concurrency (not thread-based), mostly in other languages, and a few ones allow concurrency to be much better encapsulated (though this is still a current research topic in programming languages). So it's an open question whether this applies to concurrency per-se. Oct 27, 2013 at 23:39
  • @Blaisorblade - C++11 introduced it's own threading library, so yea, it's part of C++ now. Oct 31, 2013 at 19:00
  • @MichaelKohne: I didn't claim that C++ doesn't support multithreading. I said that threads are not C++-specific, because many other languages have them. I just noted that the problems described apply to threads as an interface to concurrency. Nov 3, 2013 at 19:51
  • I would say "race condition" is a better word for this core issue. That is, programmers may not need to work on or use the concurrency framework at all, but if they write any C++ code, and their code could be potentially called from more than one thread, then they need to think about race conditions in general, in all of their code written.
    – rwong
    Nov 4, 2013 at 1:33
  • It reminds me of a miscommunication with a coworker that happened years ago. A coworker asked another coworker: is this (some function) thread-safe? The other coworker answered yes. The coworker who asked then went on to use it from multiple threads, and got unexpected results (it did not crash, but multiple operations were applied onto the same object). It turned out the coworker who asked did not have the mental model of what "thread-safe" means, and mistook the response as "I can do whatever I want."
    – rwong
    Nov 4, 2013 at 1:36
10

The obvious answer is const correctness: since const/volatile qualification is infectious, once one part of the code started using it, every (directly or indirectly) calling code must also be const correct, or cast away constness explicitly.

As with exceptions, however, this is obviously ultimately a good thing. More so even, because unlike exception safety it’s stringently verified by the compiler.

1
  • 2
    Moreover, const-correctness is transparent: it's only about the type you give to a function (which is always visible) and the compiler will yell at you if you get it wrong. I was thinking of more opaque things, where you have no idea something's wrong until is too late (and even then, it'll be hard to figure it out). But your answer is interesting anyway, hence upvoted. Oct 26, 2013 at 0:26
10

Pointers.

  • Does the pointer point to memory on the stack?
  • Does the pointer point to memory on the heap?
  • Does the pointer point to a single object?
  • Does the pointer point to an array?
  • Does the pointer point to a location in the middle of an array?
  • Is the pointer valid?
  • Is the pointer mangled?
  • What code "owns" the pointer?
  • Should the referenced object be manually deallocated? If so how?
1
  • 1
    +1 specifically because of the question about pointer ownership. Without smart pointers, ownership really does propagate throughout the whole team.
    – JKor
    Nov 1, 2013 at 3:01
3

Another possibility is operator overloading. Once one part of the codebase starts to tinker with overloaded operators everyone tends to start second guessing just what exactly any given object they are working with is actually doing. It doesn't explicitly propagate through the codebase the way exceptions and const correctness do, but it's definitely something that can start to cause issues if the whole team isn't on the same page about when, how, and why to use it.

1

The only one besides const correctness (seen above) that comes to mind is stream(ing) state. If you write C++ code where you use objects and subobjects and object hierarchies chances are, you'll eventually want to send or receive data to/from the operator of the program. You can write simple streaming operations that will compile and will be semantically correct...

std::ostream& operator<< (std::ostream&, MyClass const&) {...}
std::istream& operator>> (std::istream&, MyClass&) {...}

...But once you do, you'll never have any guarantee that what you are trying to write (or most importantly, read) follows the same format as what the client is sending you. There's too many weirdnness cases going on with streams, even worse if you have to pass streams or stream flags as arguments down your function call chain… which is what streaming of classes is usually implemented as. So streaming can be defined as "insidious" as you used the term above, or perhaps even as "viral" (though not anywhere to the same degree as const-correctness).

Have a member deep down your class hierarchy that is a string? Surprise, the client better sends a single word, or else. Have some numbers you want to serialize? You better check, save and restore the stream flags at every function call depth, because you never know who's the idiot who just set his stream to octal output before calling your function. Or worse - who just called something like setfill and setw and thus broke the input/output formatting of your first -and only your first- integral members because those states don't propagate. Oh and let's not ask about streams and internationalization.

There's no warning in the language whatsoever that you are streaming the right way, or the wrong way, or even streaming at all. Asked client code for a stream to pass to write data backup to? You don't really have a way to know that the stream points to /dev/null. (On the other hand, you can claim incredible backup speeds and compression rates that way!)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.