开发者

Avoid warning 'Unreferenced Formal Parameter'

I have a super class like this:

class Parent
{
public:
    virtual void Function(int param);
};

void Parent::Function(int param)
{
    std::cout << param << std::endl;
}

..and a sub-class like this:

class Child : public Parent
{
public:
    void Function(int param);
};

void Child::Function(int param)
{
    ;//Do nothing
}

When I compile the sub-class .cpp file, I get this error

warning C4100: 'param' : unreferenced formal parame开发者_StackOverflow社区ter

As a practice, we used to treat warnings as errors. How to avoid the above warning?

Thanks.


In C++ you don't have to give a parameter that you aren't using a name so you can just do this:

void Child::Function(int)
{
    //Do nothing
}

You may wish to keep the parameter name in the declaration in the header file by way of documentation, though. The empty statement (;) is also unnecessary.


I prefer using a macro, as it tells not only the compiler my intention, but other maintainers of the code, and it's searchable later on.

The method of commenting out the argument name can easily be missed by people unfamiliar with the code (or me 6 months later).

However, it's a style-issue, neither method is "better" or more optimal with regards to code generated, performance or robustness. To me, the deciding factor is informing others of my intent through a standardized system. Omitting the parameter name and putting in a comment would work equally well:

void CFooBar::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
    UNREFERENCED_PARAMETER(pNMHDR);

Alternatively:

void CFooBar::OnLvnItemchanged(NMHDR* /* pNMHDR */, LRESULT *pResult)
{
    // Not using: pNMHDR

I would say that the worst solution is suppressing the warning message; that that will affect your entire file or project, and you'll lose the knowledge that maybe you've missed something. At least by adding the macro, or commenting out the argument name, you've told others that you've made a conscious decision to not use this argument and that it's not a mistake.

The Windows SDK in WinNT.h defines UNREFERENCED_PARAMETER() along with DBG_UNREFERENCED_PARAMETER() and DBG_UNREFERENCED_LOCAL_VARIABLE(). They all evaluate to the same thing, but the difference is that DBG_UNREFERENCED_PARAMETER() is used when you are starting out and expect to use the parameter when the code is more complete. When you are sure you'll never use the parameter, use the UNREFERENCED_PARAMETER() version.

The Microsoft Foundation Classes (MFC) have a similar convention, with the shorter UNUSED() and UNUSED_ALWAYS() macros.

Pick a style and stick with it. That way later on you can search for "DBG_UNREFERENCED_PARAMETER" in your code and find any instances of where you expected to use a argument, but didn't. By adopting a consistent style, and habitually using it, you'll make it easier for other and yourself later on.


Another technique that you can use if you want to keep the parameter name is to cast to void:

void Child::Function(int param)
{
    (void)param;   //Do nothing
}


As @Charles Bailey mentioned, you can skip the parameter name.

However, in certain scenarios, you need the parameter name, since in debug builds you are calling an ASSERT() on it, but on retail builds it's a nop. For those scenarios there's a handy macros (at least in VC++ :-)) UNREFERENCED_PARAMETER(), which is defined like this:

#define UNREFERENCED_PARAMETER(x) x

Note that the simple cast @R Samuel Klatchko posted also works, but I personally find it more readable if the code is explicit that this is an unreferenced parameter vs. simple unexplained cast like that.


Pragma works nicely too since it's clear you are using VS. This warning has a very high noise to benefit ratio, given that unreferenced parameters are very common in callback interfaces and derived methods. Even teams within Microsoft Windows who use W4 have become tired of its pointlessness (would be more suitable for /Wall) and simply added to their project:

#pragma warning(disable: 4100)

If you want to alleviate the warning for just a block of code, surround it with:

#pragma warning(push)
#pragma warning(disable: 4100)
void SomeCallbackOrOverride(int x, float y) { }
#pragma warning(pop)

The practice of leaving out the parameter name has the downside in the debugger that you can't easily inspect by name nor add it to the watch (becomes confused if you have more than one unreferenced parameter), and while a particular implementation of a method may not use the parameter, knowing its value can help you figure out which stage of a process you are in, especially when you do not have the whole call stack above you.


Since C++17 you also can use [[maybe_unused]] to avoid such warnings:

class Parent
{
public:
    virtual void Function([[maybe_unused]] int param);
};


I would use a macro to suppress the unreferenced formal parameter warning:

#define UNUSED( x ) ( &reinterpret_cast< const int& >( x ) )

This has the following advantages:

  • Unlike #define UNUSED( x ) ( void )x, it doesn't introduce a need for the full definition of the parameter's type to be seen where no such need may have existed before.
  • Unlike #define UNUSED( x ) &x, it can be used safely with parameters whose types overload the unary & operator.


What about just adding reference with a comment:

void Child::Function(int param)
{
    param; //silence unreferenced warning
}

This was also suggested here: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4100?view=vs-2019

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜