Author: Chloé Lourseyre
Editor: Peter Fordham
This week we’ll discuss a serious topic affecting the developer community. This touches several languages, but the C++ community is one of the most affected by it1.
There are several “ways” to write C++. I mean “way” as a collection of constraints and circumstances that will affect what you can do, what you should do, and how you can and should do it.
This may seem vague, but think of it as types of environments that can drastically change your approach to the code you reading, editing, and writing.
Based on my experience, I can distinguish three types of development2.
The three categories
The (almost) solo development
This is the type of development that has the fewest constraints (if not none at all). When you are developing alone or with very few collaborators, you can freely choose what to do and how you want to do it.
The collaborative licensed development
When you are on a bigger project, you will see constraints arise. Most of the time, these constraints will consist in which library you can or cannot use.
For instance, if you want to sell your software, you can’t use a JRL licensed software, because it prohibits commercial uses.
This is generally a type of development that concerns small companies or freelance developers.
The industrial development
Some projects are launched by big companies or company groups. They can be developed over numerous years (even decades if you include the maintenance phase of these projects), but more importantly they have heavy constraints overs which libraries you can use and in what environment the development takes place.
This is typically the type of development where the C++ version is the oldest (often prior to C++17, sometimes even in C++03). This is because the management (not to say the salesmen) that pilot the budget of this kind of project and decide whether the environment can be migrated or not.
A lot of developers that work on this kind of project arrive in the middle of it and face heavy resistance when they try to improve the environment3.
In this kind of project, you often have to deal with legacy code or with a part of the codebase that you can’t edit4.
What is specific to C++?
C++ is a complicated language, not only because of its syntax and language specification, but also because there are hundreds (if not thousands) of different possible environments.
There are dozens of C++ compilers, ported on numerous operating systems. As of today, there are 5 different versions of the standard5 that are present in professional projects.
It is thus essential for each C++ developer to adapt their advice to the person they are talking to. Because depending on the situation, you may say the complete opposite of what you would have said otherwise.
Clashing grounds
There is one place where the three types of development can be represented at the same time: on the internet. When you lurk on dedicated forums, you’ll eventually find people that are currently working on the different types of projects.
Overall this is a good thing, that all kinds of developers can meet over the internet, but it can lead to communication issues.
Indeed, if one developer who has only performed one type of development ever tries to give advice or feedback to a developer from another type of environment, a lot of this advice and feedback will not take the developer’s constraints and circumstances into account and will not be useful.
Let’s take a few examples to illustrate that.
Example from r/cpp
Here is an example that comes for Reddit, specifically from the subreddit r/cpp:
This example is typical: while courteous, it misses the point and is based on two sophisms:
- “Every modern C++ compiler produces warnings if […]”. It greatly depends on what “modern” means, but there is a lot of compilers that do not work like your standard compiler. I’m thinking about compiling for embedded systems, experimental compilers, and home-made compilers that you can sometimes encounter on very specific projects, or even older compilers that did not implement the said warning at that time. Trying to generalize in this context is somewhat of a fallacy, especially since “printf API […] doesn’t enforce it”.
- “[…] honestly you should have compiler warnings enabled anyway.”. I hear that a lot, and I think most of those who say it never have worked under project and environment constraints. When you arrive on a project, you don’t always have a say on how the environment works, especially if the project was ongoing for several years when you arrived. Our work (as C++ experts and such) is to try and change mentalities, but sometimes it doesn’t work, unfortunately. There are also situations where when you arrive on the projects, there are hundreds and hundreds of warnings, and the management won’t give you the time to correct them all. In this context warnings-hunting is a lost cause.
Of course, we should always try to change the world for the better and try to destroy improper environments, but denying the existence of these contexts is denying the reality, how the world of development sometimes really works.
When that occurs, try to add nuance to your statements, leave it open for people to explain what are their constraints.
Instead of
“Yes you have to enable -Wall but honestly you should have compiling warnings enabled anyway.”
say something like:
“If you can you should enable -Wall because it will help you prevent the issue and others as well.”
Example from SO
Here is another example, taken from Stack Overflow:
Pretty short, but a lot to say nonetheless.
“Best advice is not to write macros like that.” Okay, no problem, but why? Because of how macros work? Because you can’t do whatever you want to do with it? Because macros are bad design and there is a working alternative?
The question states the following constraint:
Is the question “Why do you need to use __LINE__
?” really relevant? Since the question is based on the statement just above, whether you know why does the user need __LINE__
or not won’t help the original poster6.
Writing relevant advice is really easy when you put your thought into it. For instance:
This comment simply states that pointers are usually bad, while admitting that depending on the case they may be needed. It has been written to hint at the original poster about the dangers of pointers while remaining relevant.
Wrapping up
When you want to be helpful to other developers, you have to pay attention to their circumstances. Your answer won’t reach its target if it is irrelevant.
Plus you have to ask yourself: are you really helping anyone if your advice can be summarized by “You have to change your environment” to someone who can’t or won’t? You have to adapt to these situations, put your words into perspective, so the person you are talking to will acknowledge your advice, even if they can’t apply it directly.
It’s easy to fall into sophism and authoritative arguments. Always try to explain your arguments, even if they seem trivial to you. This will give weight to them. Moreover, maybe it’s trivial to you but it may not be so for others. And if you don’t manage to simply explain your argument, there is a really good chance that it’s a fallacy.
Thanks for reading and see you next week!
Author: Chloé Lourseyre
Editor: Peter Fordham
Addendum
Notes
- In this article, I’ll use C++ to illustrate, but everything that is said can be applied to any programming language. I explain why C++ is specifically affected by this later in the article.
- Depending on your own experience, you may discover other types of development. They supplement the existing ones.
- The definition of improve here is the key. What a new developer on a project might consider an improvement isn’t the same as what a senior developer, project manager, accountant, salesman or customer would consider an improvement. “It’s great that you’ve spent a year bringing the codebase up to C++20 with new GCC and clang , but you haven’t fixed any of the reported bugs, implemented the new features we promised to the customer and now we don’t support our legacy platform anymore…”
- For instance: because it is owned by another team or company, because it has already been sold to the client, or because it has already been QA’d and it’d take weeks to be QA’d again.
- I’m only counting from C++03 (so C++03, 11, 14, 17 and 20) since C++98 is very similar to C++03.
- It may sometimes occur that the original poster states a constraint that they could avoid. But it is unconstructive to “babysit” the OP in that case, it would be better to propose alternative with examples.
“Is the question “Why do you need to use __LINE__?” really relevant?”
In the vast majority of cases I’ve seen, yes — because the user has tunnel vision and has an X/Y Problem.
Internet forums like S.O. are full of people asking strange questions, and then after 5 follow-up questions we learn that they actually have a common task which can be solved in a much simpler manner than they’re proposing.
To respond to every question literally is a waste of our time and a disservice to them. Whenever one is doing something so far off the beaten path to make other practitioners say “Wait a minute, *why* would you want to do that?”, it’s worthwhile to call a time out.
In the rare situation where these constraints have a reasonable justification, the people asking are always eager to include it in the question.
Your comment is not false, but you’re missing something: sometimes, though forum fellows also have tunnel vision and see a XY problem where there is none. Some people are just incapable of understanding that one may have some hard limitation that can come from many things. That is what I’m trying to highlight in the article.