views:

110

answers:

6

I'm reviewing our Visual C++ code base and see lots of helper functions with really short bodies. Like for example this:

inline int max( int a, int b ) { return a > b ? a : b; }

the problem is when code is debugged in Visual Studio debugger it's impossible to immediately see what a and b are upon entering the function with F11 ("step into"). One just presses F11 and the "current line" pointer points onto the line with the opening brace, then after F10 ("step over") control goes out of the function. That's not very convenient.

The alternative would be to rewrite all those function so that the body payload occupies a separate line:

inline int max( int a, int b )
{
    return a > b ? a : b;
}

now when F11 is pressed the "current line" pointer points onto the opening brace, then after F10 control passes onto the payload and one can see what values a and b have. If one doesn't care and just entered this function while some complex expression is being evaluated he can press Shift-F11 and bail out of the function - but he could do this in the former case as well, so there're no major negative changes in debugging experience.

Are there any drawbacks in such code transformation? Any reasons to keep the function body on the same line as the function signature?

A: 

Do you set the breakpoint by clicking on the left side of the code window? Try positioning the cursor over the return statement and pressing the appropriate keyboard shortcut instead, e.g. F9. Only a single statement should be selected as the breakpoint, just like selecting a whole line in the second sample.

lbruder
The problem is the debugger executes code line-by-line, so this won't make any real difference.
sharptooth
Which version of Visual Studio are you using? In the newer ones, the debugger can step into separate statements within a line.
lbruder
I see this behavior on VS 2008.
sharptooth
Ah, my mistake. This is a C# feature not currently available in the C++ editor.
lbruder
+1  A: 

The only reasons i can imagine are, that this is such a simple method and that the file would be bigger if you don't write the method in one line. There is nothing negative about formatting it the second way. It's only positive :)

itsme
+2  A: 

There's no difference in the compiled code between the two ways of formatting your code.

Go with what ever makes it easier to debug/maintain/understand.

In this case it's having the code on a separate line.

ChrisF
+2  A: 

From what I know, C/C++ compilers disregard white spaces, so writing the function body on another line is only for better code readability.

arscariosus
A: 

I can't reproduce your problem. In Visual Studio 2008, if I step into this function using F11, the current line pointer points to the one-liner, and I can see the values of a and b.

Which version of Visual Studio are you using?

As to your question, this is purely subjective. Personally, I prefer one-liners to be on one line. But that's just me, I like to have as much code as possible on the screen at any time.

knatten
+2  A: 

IME you will keep running into this, no matter how many functions' bodies you change (thereby confusing everybody who's trying to review their changes in SVN or whatever you use). It's just too common a coding convention to completely eliminate it from a sufficiently big codebase.
And even if you managed fix all these function definitions (which is, from my POV, an uglification of the code), you will still run into code like f(g()+h(), i()) where you want to debug into the call to f() without having to go through g(), h(), and i(). Essentially, this is the same problem: some code put into a single line and you want to debug through part of it, only. Are you proposing to change (uglify) all such code, too?
You're better off learning to deal with this.

The way I deal with this in VS is to fire up the CPU window through whatever shortcut your IDE is configured to (it's Alt+8 for me) and step through the assembly instructions displayed there far enough for the stack frame to be established. If you keep the "Locals" watch window open you will be "far enough" when the local variables pop into existence. Given some time you will learn to read the machine instructions good enough to judge this just by looking at the assembler code.

sbi
I see your point. Yes, I understand that I will keep running into this anyway. The case is there's a small subset of such functions used just about everywhere and making just them more convenient would make debugging maybe two times easier.
sharptooth
@sharptooth: I've been using the disassembler view since...well, it feels like forever, and I don't get what the problem is. Besides there are other cases where you need this anyway, unless you want to debug through heaps of code just to debug into one call.
sbi
@sbi: I think of that `f(g()+h(), i())` case as the "hokey-cokey". In-out-in-out-in-out-in, and there you are in `f`! With I guess an extra in-out if `g()+h()` calls an overloaded `operator+`.
Steve Jessop
@Steve: Yes, you can do this. It's faster, though, (and from a certain complexity of the expression it's also easier) to look at the disassembled code, set the cursor point immediately before the call to `f()`, and invoke Debug/RunToCursor. You are then free to close the disassembly window and debug in the source code again.
sbi
Oh yes: I don't mean to say that your way is bad, and I do like the disassembly window. I just mean that if I want to "step in" to something I generally just give it a go. If I've stepped into the wrong thing I can step back out and try again, look at the disassembly, open the function I actually care about and set a bp in there (as you say that would be in its disassembly in the one-liner case the questioner originally raised), or anything else that feels like it might work...
Steve Jessop