What is the purpose of commenting out function argument names? [duplicate] - c++

This question already has answers here:
Why comment parameter names rather than leave it as it is
(6 answers)
Closed 8 years ago.
I'm working with this sdk that generates a skeleton plugin project, as in, all the functions required by the host application are there, just not filled.
Initially, all the function definitions are sorta like this:
void Mod1::ModifyObject(TimeValue /*t*/, ModContext& /*mc*/, ObjectState* /*os*/, INode* /*node*/) {}
With the argument names commented out, why is that? As far as I can tell, if I'm not using the arguments, it makes no difference whether the names are there or not.

I guess there are two reasons for this:
It's deliberate to essentially only implement what's necessary: Function names and their signatures. They don't define any names, so it's up to you to either pick the suggestions or your own (or none at all).
It's to avoid extra-pedantic compilers complaining about unused variables that are defined as parameters. If you don't need a parameter, it's most efficient to simply drop it (unless you need it in some other implementation, but the compiler won't necessarily know about that). But then again they could also complain about params that are there, but not named (although you could consider that intentionally omitted).

Some compilers will issue a warning about unused named parameters, but not about unused unnamed parameters. GCC is one such compiler, if the -Wunused-parameter option is used, enabled by -Wextra.
The theory behind this is that an unused named parameter is more likely to be a mistake than an unused unnamed parameter. Of course, that theory doesn't apply to all code.

When you turn on treat warnings as errors, and you don't use a parameter, you'll need to comment out its name or delete it entirely.
There are sometimes macros such as Q_UNUSED in Qt, or you can just reference it in code without doing anything to make the compiler shut up.
void foo(int unused) {
(void) unused; // So the compiler doesn't emit a warning.
}

Related

Mark as deprecated function parameters in C++14

Reading this blog post and its comments, I have noticed that it gives as an example the possibility of marking specific function parameters as deprecated, as in (exaple taken from the post):
// Deprecate a function parameter
int triple([[deprecated]] int x);
Now I was wondering, what is a good use case for such a feature? No one in the comments of that post or anywhere else I have searched seem to have a clue.
EDIT:
To see it in action, there is a compilable example on goldbolt
Say you had a function like this:
void* allocate(std::size_t sz, void* hint = nullptr) {
// if you give `hint` it *might* be more efficient
}
And then you decided that it is no longer worth the effort to do stuff based on hint. So you would do this:
void* allocate(std::size_t sz, [[deprecated]] void* hint = nullptr) {
// `hint` is ignored. The compiler warns me if I use it in the
// function body accidentally, and people reading the function
// signature can see that it is probably going to be ignored.
}
This allows the library to keep the same signature/ABI (So you don't need to recompile stuff that uses it and legacy code can still keep using it without doing any harm), and also prevents it from accidentally being used again when changing the function.
But this is mostly for developers of the function, not the users of the function, in the future so they know why a seemingly "useless" parameter is there.
I would also think that this would disable the "unused parameter" warning with the -Werror=unused-parameter flag in gcc/clang, but it doesn't. Using (void) deprecated_parameter also issues a warning about using a deprecated parameter, so this seems like a bug. If it did disable the unused param warning, that would be another use case for [[deprecated]].
The rule is that the attribute is valid on, amongst other things, variable declarations (broadly). It's not specifically permitted for such declarations found in function arguments.
The original proposal, N3394, doesn't mention such a use case, either, and neither does the documentation for the original feature in GCC (which regardless accepts the equivalent usage) or in VS (I didn't check Clang).
As such, I think it's an "accident" that this is permitted, not something that anyone really had in mind as being useful.
Could it be useful to document deprecated defaulted arguments, as Artyer explores? Yes, potentially, and vaguely. But as Artyer also found, mainstream compilers don't actually react to this usage in a helpful manner.
So, at the present time, it's not useful, and the language feature wasn't particularly designed to be useful in this case.
Imagine a library that is implemented, used and maintained for many years. This library is used in multiple projects.
If you would simply remove the parameter, all the projects would have to immediately adapt the source code to be able to compile again, after they upgraded to the new library version.
If a default value is added to the parameter, but the parameter not used anymore, the projects would still compile without any change, but nobody would note that something has changed at all, and maybe some behaviour/feature that was controlled by this parameter does not work anymore.
So, by marking the parameter as deprecated the projects can compile without a change, but they get a warning that something has changed and that they should change their source code, because sooner or later this parameter will disappear.

Pawn's "stock" function homolog in C/C++ [duplicate]

This question already has answers here:
Do unused functions get optimized out?
(8 answers)
Closed 6 years ago.
I wonder if some C/C++ compilers implementing something similar to Pawn's stock keyword.
In Pawn, you can declare a function like that:
stock xfunc(a, b)
{
[...] // Bla bla
}
The stock keyword tells the compiler to simply not include the function in the compiled binary if it's not called somewhere in the code. This makes the function facultative so to speak, and it won't increase the binary size if its not used.
I would find it useful to have something like this in C/C++ because I want to include some functions I will not immediately use in the first iterations of my program/code. Of course, some people might tell me there's other ways to do this like using preprocessor macros, etc etc. I'm not asking for another way, I want something that permits me to make use of those functions later without having to uncomment them, change a macro to make them get compiled, etc (i.e. seamlessly). BUT... without compiling them and thus increasing my executable size when I don't use them!
A handy feature I would say.
Thanks!
P.S. If the answer is "it's not included in the language standards", are there any compilers that do it with specific pragmas, unofficial keywords, etc.?
EDIT: Should I mention, I'm mostly interested into this feature for virtual function. I'm aware function level linking exists for standard functions, but what about virtual ones? I think normally, if im not mistaken, virtual funcs get compiled even if not used to maintain class layout compatibe with a class prototype? Could you confirm? Thanks
Any modern optimizing compiler/linker will do "dead code elimination" and strip out not just uncalled functions, but also unused bits of called functions.

Why is void used in this manner with an inline function? [duplicate]

This question already has answers here:
Why cast unused return values to void?
(10 answers)
Closed 6 years ago.
I just ran across this in some sample code and I've never seen it used before. For an inline function which returns a type but the return value is not used, the author preceded the call with a (void). Does this actually do anything?
Example:
inline some_object& SomeClass::doSomething();
SomeClass o;
(void)o.doSomething();
This is typically done when using a tool like Lint which has been configured to issue a warning if you call a function and ignore its return value.
This is (IMO) a horrible practice that's fostered by some tools1 that give warnings about calling a function and ignoring what it returns.
The right way to deal with the problem is to give the tool a list of functions whose return values can reasonably be ignored. If the tool doesn't support that, it's probably useless and should be thrown away. In the case of a compiler, you may not be able to throw away the tool itself, and may have to settle for just globally disabling that warning.
1. Most often something like lint, but some compilers can do the same.

What is the use of a statement with no effect in C++? [duplicate]

This question already has answers here:
What is the purpose of the statement "(void)c;"?
(3 answers)
Closed 8 years ago.
In one library that I am using I saw this code:
template<typename T>
void f(SomeTemplatedClass<T> input)
{
(void)input;
...
use(input); // code that uses input
}
I have no idea what is the meaning of this code. If I remove the cast to void, I get a
statement has no effect
warning in gcc. So I suppose someone did it purposefully and purposefully added the cast to get a rid of the warning.
Do you have any experience with a statement that has no effect, yet it is needed for some reason?
EDIT:
Is it safe to assume that this has nothing to do with templates? For example circumventing an old compiler bug or the like?
This construct is a common way of tricking the compiler into not emitting a warning for unused parameters. I have not seen it used for any other purpose.
(void)input;
While it is common, it is also a really bad idea.
it is highly platform dependent -- it may work on one compiler and not another.
it is unnecessary. There is always a better way to deal with unused parameters. The modern way is to simply omit the parameter name.
it can get left behind if the code changes and the parameter is now used (as appears to be the case here).
it can backfire. Some compilers may treat this as invalid.
According to the C++ standard N3936 S5.4/11:
In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value expression. The expression is evaluated and its value is discarded.
A compiler would be entitled to observe that there is no side-effect and therefore this construct deserves at least a warning. According to #chris, MSVC is one of those compilers.

What do the "..." mean in virtual void foo(...) = 0;?

Pretty simple question I think but I'm having trouble finding any discussion on it at all anywhere on the web. I've seen the triple-dot's as function parameters multiple times throughout the years and I've always just thought it meant "and whatever you would stick here." Until last night, when I decided to try to compile a function with them. To my surprise, it compiled without warnings or errors on MSVC2010. Or at least, it appeared to. I'm not really sure, so I figured I'd ask here.
They are va_args, or variable number of arguments. See for example The C book
Triple dots means the function is variadic (i.e. accepts a variable number of parameters). However to be used there should be at least a parameter... so having just "..." isn't an usable portable declaration.
Sometimes variadic function declarations are used in C++ template trickery just because of the resolution precedence of overloads (i.e. those functions are declared just to make a certain template instantiation to fail or succeed, the variadic function themselves are not implemented). This technique is named Substitution failure is not an error (SFINAE).
It's called ellipses - basically saying that function accepts any number of arguments of any non-class type.
It means that the types of arguments, and the number of them are unspecified. A concrete example with which you are probably familiar would be something like printf(char *, ...)
If you use printf, you can put whatever you like after the format string, and it is not enforced by the compiler.
e.g. printf("%s:%s",8), gets through the compiler just the same as if the "expected" arguments are provided printf("%s:%s", "stringA", "stringB").
Unless really necessary, it should be avoided, as it creates the potential for a run time error to occur, where it might otherwise have been picked up at compile time. If there is a finite, enumerable variation in the arguments your function can accept, then it is better to enumerate them by overloading.