Friday, July 18, 2014

Is the non-pointer syntax for declaring function pointer parameters not worth mentioning?

In my view, one of the most important favors a technical writer can do for his or her readers is shield them from information they don't need to know. One of my standard criticisms of authors is "S/he knows a lot. S/he wrote it all down." (Yes, I know: the "his or her" and "s/he" stuff is an abomination. Please suffer in silence on that. There's a different fish I want to fry in this post.)

I try not to commit the sin of conveying unimportant information, but one of the hazards of spending decades in this business is that you learn a lot. After a while, it can be hard to evaluate what's worth knowing and what's best left unsaid. With that in mind, the current draft of Effective Modern C++ contains this passage (more or less):

Suppose our function f can have its behavior customized by passing it a function that does some of its work. Assuming this function takes and returns ints, f could be declared like this:

void f(int (*pf)(int)); // pf = "processing function"

It’s worth noting that f could also be declared using a simpler non-pointer syntax. Such a declaration would look like this, though it’d have the same meaning as the declaration above:

void f(int pf(int)); // declares same f as above

One of my reviewers argues that the second way of declaring a function pointer parameter is not only not worth noting, it's not worth knowing. That means I should omit it. But I find myself reluctant to do that. I like the fact that function pointer parameters can be declared without throwing in additional parentheses and figuring out which side of the asterisk the parameter name has to go on. But maybe that's just me.

So what do you think? Should I jettison the aside about the asterisk-free way to declare the parameter pf, or should I keep it?

My initial reaction was basically OMG WHY DID NOBODY EVER TELL ME THIS? However, I'm not sure it actually matters to a general C++ audience.

As I assume you go on to say after that excerpt, first-class function parameters should almost always be generic function objects in modern C++ (either a template type, or type-erased with std::function) rather than function pointers. That being the case, your readers probably don't need to know how to write function pointer parameters. They may sometimes need to know how to read them, in order to deal with legacy code, but given the seeming rarity of that syntax, it's probably not worth teaching for those purposes either.

@grey wolf, the type passed to std::function in your example isn't a function pointer type, you are passing a function type. The type-decay from function to function pointer just occurs in function parameter declarations.

I agree with the reviewer and would further say that the automatic 'adjustments' to argument types, as the C++ spec calls them, are an abomination and they should not be used. This is definitely one of those things inherited for C compatibility that makes C++ worse.

No, in fact the template syntax is doing what it should do precisely because does not involve the the 'adjustments' that are specified for function parameters. Knowing about the adjustments should have no bearing on knowing how to write a function's type.

Well, I've been doing C++ for a couple decades and didn't know about this one. I guess I should feel bad about that but I've never seen it used either. I think it's clearer, so its lack of popularity may simply be an example of a widespread ignorance.

Thanks to everybody for their comments. I've decided to keep the comment in the draft book.

FWIW, many of the other issues that have been raised here (e.g., the most vexing parse, function pointer types vs. function types during template type deduction,specifying function types for use with std::function, etc.) are discussed elsewhere in the book.

The second syntax seemed cool at first glance. But it doesn't work if the return type is a pointer :( This means that you have to think what syntax to use depending on the return type, and that's a reason enough not to use or mention it.