This point brings to mind another pet peeve of mine: source code formatted to 80 columns.
I used to feel the same and thought it was stupid/silly to have this column width limit but as I have become more experienced as a software developer I regret not enforcing it as a standard on my projects.
For example, take this (source Looking Glass project):
const uint64_t pending =
atomic_load_explicit(&g_state.pendingCount, memory_order_acquire);
if (!lgResetEvent(g_state.frameEvent)
&& !forceRender
&& !pending
&& !app_overlayNeedsRender()
&& !RENDERER(needsRender))
{
if (g_state.ds->skipFrame)
g_state.ds->skipFrame();
continue;
}
vs unlimited line length
const uint64_t pending = atomic_load_explicit(&g_state.pendingCount, memory_order_acquire);
if (!lgResetEvent(g_state.frameEvent) && !forceRender && !pending && !app_overlayNeedsRender() && !RENDERER(needsRender))
{
if (g_state.ds->skipFrame)
g_state.ds->skipFrame();
continue;
}
You tell me which is easier to follow if you didn't write this code? The human eye likes lists, they are easy to follow. When code gets too wide it becomes easy to miss errors in a line of code.
Well, I must be the odd man out, because the second is WAY easier to scan for me. When I look at code, for instance your example, I just scan that there's an if statement, and if true, it does something. I typically don't want to analyze all the conditions of the if statement when I'm scanning it. Take your first example though, and often programmers will put the opening brace at the end of the line of the last condition of the if statement, which makes it even worse. Of course I can follow code written that way, but it just takes more time for the brain (my brain at least) to process where the lines of code are, vs. the lines on the screen. Just for example, I can see/process a line I'm scanning in let's say under 100 milliseconds if it's all on one line. If it's broken into multiple lines, I first need to scan it to see where the end of the "if line" is, and then process it. That additional brain processing will maybe add another 100 milliseconds or more, and if a brace is at the end of the line, instead of on a line by itself, it takes even more time. Maybe that's just me, but absolutely quickly scanning code, and not analyzing it in any detail is a huge percent of the amount of time I spend, and I can sometimes be scanning code for several hours a day. The difference in time between the two styles, at least for me, is very significant.
Many years ago, when I first saw code where the various conditions of an if statement, or the various parameters to a function were on separate lines, of course I thought, "oh, that's easier to see each item lined up vertically". But in actual practice, it just isn't as efficient for me, because of the fact that my brain works the most efficiently by easily processing one line as one concept/statement. Certainly it is a tradeoff. If really analyzing in detail a line of code, vertically arranged parameters, etc. is faster. For scanning, where details aren't necessary, it's slower. So it depends on the ratio of scanning to analyzing.
Anyways, one key point is the indentation. When I see an if statement, etc., then the following line is indented, my brain immediately thinks the following line is to executed if the condition is true. Then it takes a bit of time to realize, "no, it's not the next line after the if statement, but it's a continuation of it." Maybe if there was a good method, such as colorization to indicate the if statement, with all of it's lines (conditions), it wouldn't be so distracting for me. But as it is, using indentation for two different purposes makes it less efficient. And maybe other programmers don't have the same issue as me if they haven't had it so engrained in their mind to do things one way (ie. the whole statement all on one line).
For the example you gave, my personal coding style for the second one would be:
const uint64_t pending = atomic_load_explicit (&g_state.pendingCount, memory_order_acquire);
if ((!lgResetEvent (g_state.frameEvent)) && (!forceRender) && (!pending) && (!app_overlayNeedsRender ()) && (!RENDERER (needsRender)))
{
if (g_state.ds->skipFrame)
{
g_state.ds->skipFrame ();
}
continue;
}I use parenthesis to delimit each of the conditions of the if statement. To me, it makes it easy to scan the statement and see each condition, whereas in your example they tend to run together without the parenthesis. I also ALWAYS add braces to every if statement, such as the second one. Yeah, it takes up two more lines to add those opening and closing braces, but it's just another visual cue to me to show exactly where the if block begins and ends, and also I can easily add code inside the if block later. But anyways, that's a separate issue.
This is especially true for code which I haven't touched for many years.
Exactly my point here, you know your coding practices and how you would structure your conditionals, what you would name things, etc. as such scanning your own code even years later is a sinch vs someone else's code.
Enforcing a width limit not only helps prevent mistakes it also prevents developers from doing stupid things like too many layers of nested if statements:
void doSomething(void)
{
if (a)
{
something
if (c)
{
something
something
if (d)
{
something
something
}
}
}
}
All that nesting makes it hard to follow, especially when the function gets quite long. Now compare it to the following.
void doSomething(void)
{
if (!a)
return;
something;
if (!c)
return;
something;
something;
if (!d)
return;
something;
something;
}
Yes, the second is better. But just having a long line length available doesn't mean it should be used and an excuse for what ends up being bad coding style. In fact, I rarely use long lines. Typically the only place I use lines which go much over 100 characters is for if statements and function calls, and even then, if they become too unwieldy, then I'll modify things so that it's not the case. Of course, giving unlimited line lengths to inexperienced programmers, or programmers who've never learned proper coding style is an invitation for abuse. But there's plenty of other things besides unlimited line lengths that give rise to horrible code. In my situation, it's up to me to review the code of the software engineers who are under my supervision to see that they're practicing good coding in accordance to the standards I've specified, and if not, tell them what they're doing wrong and how to correct it. As for code written by someone outside my organization, I have no control over it, and if it's code we'll be using and need to modify a lot or frequently, we'll first convert the general format according to our standards, much of which can be done automatically, and then go over it in detail and add/adjust comments, modify bad coding style, etc.
The other time I'll go over 100 or so characters is with comments. I find it so annoying to see code that has a strict character limit per line, and see a comment that fills up one line, then on the following line has just one single last word. And comments that are written as a long paragraph, with the text just wrapping according to the limit. For normal writings, that style is fine, because it's assumed the reader will read the entire content. But for comments in code, to me it's not appropriate. Again, one line = one concept, and in the case of comments = one sentence. I try to keep the sentences of my comments fairly short, but when necessary I don't hesitate to go beyond 100 or so characters. The next sentence starts on the next line. Again, it all has to do with scanning. I read the first few words of a line of comments to see if it's applicable to what I need to know, and if so, read the whole sentence. If not, skip to the next line.