One Line of Code

One line of code should contain one line of code. Not two or six, but just one.

A common and sometimes prevailing attitude of C and C++ programmers is to cram as much functionality into a single line of code as possible. When I was first learning C using Borland's Turbo C in the early Eighties, this concept was quite vogue. When I railed against it in forums such as CompuServe (via a 1200 baud modem I might add), I was very much in the minority and did not win friends over my position. It seems that the attitude has changed some, but not enough.
When we embed multiple lines of code within a single executing function there are several results.

Multiple lines of code in a single statement conflate the concept. Instead of looking at a function that has one purpose and accomplishes one task, you may be looking at a function that accomplishes three or six tasks. Although you may think you can understand it all at once, I hold that you do not understand it as well as you do when each task is separated out into its own separate line of code.

When looking at the top level function, that has one or more parameters embedded in a function call, you cannot see the value that is really being passed in. You may be able to mentally resolve the value that you think is being passed in, but that mental image may not match reality.

Debugging: It is often the case that the debugger will not step into each of the parameter functions before stepping into the main function. Indeed, you may get to step into a parameter function and never see the main function at all. In any case, I have yet to see a compiler that provides the ability to step into each and every function in a call that contains parameters as embedded functions.
Some will say that once they step into the main function they can see all the parameters. Maybe so, but once there, you cannot step back out and easily see what let up to those parameters. If you are calling the function will an incorrect parameter, or if one of the embedded functions used to build a parameter is in error, that can be difficult to see.

I hold that each line of code should be a separate line of code. Each function call to develop a parameter should be within its own line of code and should return a value to a local variable. That variable should then be used in the function code.

Performance: I hold there is no performance hit in doing this. Indeed, I suspect that the compiler and possibly the end result will run faster.

Compiler: For each function that is embedded in a parameter position, the compiler must detect that embedded function, set up a local variable, write the code to perform the operation, save the result, evaluate any additional embedded function calls, and then finally call the top level function with the resolved parameters. This means that embedding function calls in parameters takes more compiler time than not. The compiler has an easier time when the parameters calls are performed explicitly as opposed to being embedded. (Note, I have not tried this, it is just my opinion.)

Runtime: Code space is not saved by embedding function calls into parameters. As just noted, the computer must write code and save the result somewhere. You might as well have the compiler save the values someplace where you can see them rather than hiding them from you.

Results: Following from the previous, functions don't always return what you expect. (Always keep in mind, debugging is determining where the programmer’s expectations differ from reality.) Even when the function is correct and returns what you want it to in a given instance, the result may not be what you need. You might be calling a function with the wrong arguments and not realizing that. If you see the results as an immediate product of a call to that function rather than as a result as an argument (one or more steps removed) in another function call, it is easier to recognize the problem.

Big Picture: When you are ready to step into the larger function call, I hold that it is easier to pause, and take a moment to verify that the call is correct by looking at each of the parameters and their values, and how they are developed, before stepping into the function. While you can see the arguments once inside the function, it is more difficult to see the context of the call from inside the function rather than from outside. Look at the environment from the outside with all the parameters resolved to the values used in the actual call, and then, go inside and have a look around.

If you would like to present an opposing view please send it to:
webmail at bkelly dot ws.

March 2008