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 parameter
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
Related
I develop a mac app using c++. I want to define the macro 'logi' corresponding to the call of two methods, so that method1() and method2() are being called. So I tried this:
#define logi method1 method2
It does not work. What is standard writing of this situation? thanks a lot!
At very first: If you can, avoid macros. If it is about calling two functions in a sequence, prefer defining an inline function instead:
inline void logi()
{
method1();
method2();
}
While inline just is a recommendation for the compiler – and it might choose not to do so – for such simple functions you won't find any compiler not following this recommendation (rather would the function be inlined even without keyword).
This approach is much safer – and anything you do wrong the compiler will show you right at the function definition.
If you insist on a macro: Best practice is letting it look like a function, if it behaves like such one, as in your case:
#define logi() do { method1(); method2(); } while(false)
The loop wrapping around makes this macro robust if used like a function somewhere in code, imagine it was used without like that:
if(someCondition)
logi();
Guess, method2 would get called unconditionally (well, another example showing why it's good practice always to place braces around branch and loop bodies...).
The colon is skipped deliberately, so the user is forced to place it, again making the macro behave like an ordinary function.
Be aware that for macros the pre-processor does nothing more than simple text replacement. So whatever you define, it must be valid C++ code (to be precise: the outcome, when the pre-processor is done, must be valid code). How would a macro look like, if you needed to pass arguments to your functions? Well, you need to include them in the macro definition, too:
#define logi(A1, A2, B1, B2, B3) do { method1(A1, A2); method2(B1, B2, B3) } while(false)
I guess you only forgot the ';' between the two functions. Therefore that the #define-macro only is a text-replacement in your code you need to 'end' the call of your function with a ';'.
But you might want to overthink using the #define-macro that way. It does not seem to make much sense to me to do it this way. See here on "when to use #define"
#include <iostream>
#define logi fun1(); fun2();
void fun1(void)
{
std::cout << "fun1 called\n";
}
void fun2(void)
{
std::cout << "fun2 called\n";
}
int main(void)
{
logi
return 0;
}
I've been looking for the answer to this question but it seems quite difficult to get it, which brings me finally here.
It's a syntax that we have to put the & right before pointer to member function.
For example here.
class Test;
typedef void (Test::*fpop)();
class Test
{
public:
void Op1(){}
};
int main(){
fpop pFunc;
pFunc = &Test::Op1; // we must need the &
return 0;
}
However, when I take a look at ON_COMMAND(or any other messages) in MFC, it seems a bit different from what I think is right.
VS6.0 is okay. It follows the right syntax as you see below.
You can clearly see & before memberFxn.
#define ON_COMMAND(id, memberFxn) \ // VS6.0
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)&memberFxn },
// ON_COMMAND(id, OnFoo) is the same as
// ON_CONTROL(0, id, OnFoo) or ON_BN_CLICKED(0, id, OnFoo)
But in VS2008, it goes a bit weird. There is no & before memberFxn.
#define ON_COMMAND(id, memberFxn) \ // VS2008
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
static_cast<AFX_PMSG> (memberFxn) },
// ON_COMMAND(id, OnBar) is the same as
// ON_CONTROL(0, id, OnBar) or ON_BN_CLICKED(0, id, OnBar)
Moreover, in spite of the fact that there is no & before memberFxn,
each line below works perfectly.
ON_COMMAND(ID_APP_ABOUT, CSingleApp::OnAppAbout) // &
ON_COMMAND(ID_APP_ABOUT, &CSingleApp::OnAppAbout) // no &
I tried to find why, and I was curious if it could be because of static_cast<> but it turned out that static_cast has nothing to do with it.
So I am wondering why in VS2008 I have 2 choices where I put the & or I don't have to put the &.
The Visual C++ compiler (VS2005 and VS2008) requires an ampersand (&) and the fully qualified name to form a pointer to member as per C++ standard as shown:
class Test
{
public:
void Foo() {}
void Bar()
{
void (Test::*ptr1)() = Foo; // C3867
void (Test::*ptr2)() = &Foo; // C2276
void (Test::*ptr3)() = Test::Foo; // C3867
void (Test::*ptr4)() = &Test::Foo; // OK
}
};
Most likely there are #pragmas in the MFC headers or something that suppresses the errors, for backwards compatibility reasons. Older versions of VC++ were much less conforming than the newer compilers.
The only correct way to form a pointer to member in C++ is with & and the class qualifier (in this case CSingleApp::).
The Visual C++ compiler has always been more relaxed and has allowed things not normally permitted in the language such as leaving of the qualifier when forming the pointer from inside the class' context and not needing to use & when it is strictly required.
We know that in-line are favorable as they are checked by the compiler and same operation ( like ++x ) does not evaluate more than once when passed as an argument as compared to macros.
But in an interview I was asked the specific advantages or the circumstances when a macro is more favorable to inline in C++.
Does anyone know the answer or can give a thought on this question ?
The only thing I can think of is there are some tricks that you can do with a macro that can't be done with an inline function. Pasting tokens together at compile-time, and that sort of hackery.
Here is a specific situation where macros are not only preferred, they are actually the only way to accomplish something.
If you want to write a logging function which logs not only some message, but the file & line number of where the instance occured, you can either call your function directly, typing in the file & line values (or macros) directly:
LogError("Something Bad!", __FILE__, __LINE__);
...or, if you want it to work automatically, you must rely on a macro (warning: not compiled):
#define LogErrorEx(ERR) (LogError(ERR, __FILE__, __LINE__))
// ...
LogErrorEx("Something Else Bad!");
This cannot be achieved using templates, default parameters, default construction, or any other device in C++.
Sometimes you want to extend the language in ways that aren't possible with any other method.
#include <iostream>
#define CHECK(x) if (x); else std::cerr << "CHECK(" #x ") failed!" << std::endl
int main() {
int x = 053;
CHECK(x == 42);
return 0;
}
This prints CHECK(x == 42) failed!.
In C++ specifically, one usage of MACROs that seem pop up very often (except for the debug print with file and line) is the use of MACROs to fill in a set of standard methods in a class that cannot be inherited from a base class. In some libraries that create custom mechanisms of RTTI, serialization, expression templates, etc., they often rely on a set of static const variables and static methods (and possibly special semantics for some overloaded operators that cannot be inherited) which are almost always the same but need to be added to any class that the user defines within this framework. In these cases, MACROs are often provided such that the user doesn't have to worry about putting all the necessary code (he only has to invoke the MACRO with the require info). For example, if I make a simple RTTI (Run-Time Type Identification) system, I might require that all classes have a TypeID and be dynamically castable:
class Foo : public Bar {
MY_RTTI_REGISTER_CLASS(Foo, Bar, 0xBAADF00D)
};
#define MY_RTTI_REGISTER_CLASS(CLASSNAME,BASECLASS,UNIQUEID) \
public:\
static const int TypeID = UNIQUEID;\
virtual void* CastTo(int aTypeID) {\
if(aTypeID == TypeID)\
return this;\
else\
return BASECLASS::CastTo(aTypeID);\
};
The above could not be done with templates or inheritance, and it makes the user's life easier and avoids code repetition.
I would say that this kind of use of MACROs is by far the most common in C++.
As already said, macros can use preprocessor directives: __FILE__, __LINE__ for instance, but of course #include and #define can also be useful to parameter behaviour:
#ifdef __DEBUG__
# define LOG(s) std:cout << s << std:endl
#else
# define LOG(s)
#endif
Depending wether __DEBUG__ is defined or not (via #define or via compiler options), the LOG macro will be active or not. This is an easy way to have debug info everywhere in your code that can be easily de-activated.
You can also think of changing the way memory is allocated (malloc will be redefined to target a memory pool instead of the standard heap for instance, etc...).
Inline functions are, as the name indicates, restricted to functional tasks, execution of some code.
Macros have a much broader application they may expand e.g to declarations or replace entire language constructs. Some examples (written for C and C++) that can't be done with functions:
typedef struct POD { double a; unsigned b } POD;
#declare POD_INITIALIZER { 1.0, 37u }
POD myPOD = POD_INITIALIZER;
#define DIFFICULT_CASE(X) case (X)+2 :; case (X)+3
#define EASY_CASE(X) case (X)+4 :; case (X)+5
switch (a) {
default: ++a; break;
EASY_CASE('0'): --a; break;
DIFFICULT_CASE('A'): a = helperfunction(a); break;
}
#define PRINT_VALUE(X) \
do { \
char const* _form = #X " has value 0x%lx\n"; \
fprintf(stderr, _form, (unsigned long)(X)); \
} while (false)
In the context of C++, Boost has a lot of more examples that are more involved and more useful.
But because with such macros you are in some sort extending the language (not strictly, the preprocessor is part of it) many people dislike macros, particularly in the C++ community, a bit less in the C community.
In any case, if you use such constructs you should always be very clear in what the should achieve, document well, and fight against the temptation to obfuscate your code.
A macro is just like a text replacement definition.
These essential differences that come into my mind are:
It must not be function-like. I mean it must not necessarily contain some consistent set of brackets for example.
It can be used elsewhere. Like in a class declaration scope or even in the global scope. So it must not be in the scope of another function.
You must use them if you want to perform actions that are impossible to be performed using functions:
initializing complicated tables (makes core more readable)
ease declaration of some special members like event IDs or tag classes (used a lot in MFC IMPLEMENT_DYNAMIC)
squeeze repetitive declarations at the beginning of functions
the already mentioned use of __LINE__, __FILE__, ... for logging
#include <stdio.h>
#define sq(x) x*x
int main()
{
printf("%d", sq(2+1));
printf("%d", sq(2+5));
return 0;
}
The output for this code are 5 and 17. Macros expand textually. Its not like functions.
Explanation for this example:
sq(2+1) = 2+1*2+1 = 2+2+1 = 5
sq(2+5) = 2+5*2+5 = 2+10+5 = 17
I would add two uses:
MIN and MAX, until C++0x, because the return type had to be declared by hand, mixed min and max as inlined functions would have been nightmarish, while a simple macro did it in the blink of an eye.
privacy: you can always undef the macro before exiting your header, you cannot "undeclare" an inline function (or another symbol). This is due to the absence of proper modularity in C and C++ languages.
I have sort of a tricky problem I'm attempting to solve. First of all, an overview:
I have an external API not under my control, which is used by a massive amount of legacy code.
There are several classes of bugs in the legacy code that could potentially be detected at run-time, if only the external API was written to track its own usage, but it is not.
I need to find a solution that would allow me to redirect calls to the external API into a tracking framework that would track api usage and log errors.
Ideally, I would like the log to reflect the file and line number of the API call that triggered the error, if possible.
Here is an example of a class of errors that I would like to track. The API we use has two functions. I'll call them GetAmount, and SetAmount. They look something like this:
// Get an indexed amount
long GetAmount(short Idx);
// Set an indexed amount
void SetAmount(short Idx, long amount);
These are regular C functions. One bug I am trying to detect at runtime is when GetAmount is called with an Idx that hasn't already been set with SetAmount.
Now, all of the API calls are contained within a namespace (call it api_ns), however they weren't always in the past. So, of course the legacy code just threw a "using namespace api_ns;" in their stdafx.h file and called it good.
My first attempt was to use the preprocessor to redirect API calls to my own tracking framework. It looked something like this:
// in FormTrackingFramework.h
class FormTrackingFramework
{
private:
static FormTrackingFramework* current;
public:
static FormTrackingFramework* GetCurrent();
long GetAmount(short Idx, const std::string& file, size_t line)
{
// track usage, log errors as needed
api_ns::GetAmount(Idx);
}
};
#define GetAmount(Idx) (FormTrackingFramework::GetCurrent()->GetAmount(Idx, __FILE__, __LINE__))
Then, in stdafx.h:
// in stdafx.h
#include "theAPI.h"
#include "FormTrackingFramework.h"
#include "LegacyPCHIncludes.h"
Now, this works fine for GetAmount and SetAmount, but there's a problem. The API also has a SetString(short Idx, const char* str). At some point, our legacy code added an overload: SetString(short Idx, const std::string& str) for convenience. The problem is, the preprocessor doesn't know or care whether you are calling SetString or defining a SetString overload. It just sees "SetString" and replaces it with the macro definition. Which of course doesn't compile when defining a new SetString overload.
I could potentially reorder the #includes in stdafx.h to include FormTrackingFramework.h after LegacyPCHIncludes.h, however that would mean that none of the code in the LegacyPCHIncludes.h include tree would be tracked.
So I guess I have two questions at this point:
1: how do I solve the API overload problem?
2: Is there some other method of doing what I want to do that works better?
Note: I am using Visual Studio 2008 w/SP1.
Well, for the cases you need overloads, you could use a class instance that overloads operater() for a number of parameters.
#define GetAmount GetAmountFunctor(FormTrackingFramework::GetCurrent(), __FILE__, __LINE__)
then, make a GetAmountFunctor:
class GetAmountFunctor
{
public:
GetAmountFunctor(....) // capture relevant debug info for logging
{}
void operator() (short idx, std::string str)
{
// logging here
api_ns::GetAmount(idx, str);
}
void operator() (short idx)
{
/// logging here
api_ns::GetAmount(Idx);
}
};
This is very much pseudocode but I think you get the idea. Whereever in your legacy code the particular function name is mentioned, it is replaced by a functor object, and the function is actually called on the functor. Do consider you only need to do this for functions where overloads are a problem. To reduce the amount of glue code, you can create a single struct for the parameters __FILE__, __LINE__, and pass it into the constructor as one argument.
The problem is, the preprocessor doesn't know or care whether you are calling SetString or defining a SetString overload.
Clearly, the reason the preprocessor is being used is that it it oblivious to the namespace.
A good approach is to bite the bullet and retarget the entire large application to use a different namespace api_wrapped_ns instead of api_ns.
Inside api_wrapped_ns, inline functions can be provided which wrap counterparts with like signatures in api_ns.
There can even be a compile time switch like this:
namespace api_wrapped_ns {
#ifdef CONFIG_API_NS_WRAPPER
inline long GetAmount(short Idx, const std::string& file, size_t line)
{
// of course, do more than just wrapping here
return api_ns::GetAmount(Idx, file, line);
}
// other inlines
#else
// Wrapping turned off: just bring in api_ns into api_wrapper_ns
using namespace api_ns;
#endif
}
Also, the wrapping can be brought in piecemeal:
namespace api_wrapped_ns {
// This function is wrapped;
inline long GetAmount(short Idx, const std::string& file, size_t line)
{
// of course, do more than just wrapping here
return
}
// The api_ns::FooBar symbol is unwrapped (for now)
using api_ns::FooBar;
}
I have a lot of legacy code using macro of the form:
#define FXX(x) pField->GetValue(x)
The macro forces variable pField be in the scope:
.....
FIELD *pField = ....
.....
int i = FXX(3);
int j = FXX(5);
Is there way to replace the macro, without touching user code?
Since FXX(x) has a function invocation style, I thought about inline function or something similar.
UPD:
People just used to the macro, and I want to remain it as is.
How about using a find & replace function in your favorite editor...I think it would work fine in the example you gave in your question. Replace FXX with pField->GetValue and then remove the #define line
What is pField (besides a fine example of the abomination that is Systems Hungarian)? If, by chance, it's a global variable or a singleton or something that we only need one of, we could do a nifty trick like this:
int FFX(int x)
{
static FIELD *pField = ...; // remove this line if pField is global
return pField->GetValue(x);
}
Change the int types to whatever types you need it to operate on, or even a template if you need it to support multiple types.
Another alternative, suggested by #epatel, is to use your favorite text editor's find-and-replace and just change all the FFX(x) lines to pField->GetValue(x), thus eliminating the macro invokation in your code. If you want to keep a function invokation, you culd change FFX(x) to FFX(pField, x) and change the macro to take two arguments (or change it to a function that takes two arguments). But you might as well just take out the macro at that point.
A third alternative, is not to fix that which is not broken. The macro isn't particularly nice, but you may introduce greater problems by trying to remove it. Macros aren't the spawn of Satan (though this one has at least a few relatives in hell).
What you need is a function that relies on a variable being defined. The only way to do that is to declare that variable in the same scope as the function. But then your function would use that one instead of the one declared from where your function is called.
So I'm fairly confident it can't be done.
Well, if you can put this function definition where pField is already in scope:
int FXX(int x) { return pField->GetValue(x); }
Otherwise, there's no way to get pField into the the function without affecting existing code.
This may be a case where using the macro is the best alternative. Macros may be evil, but they are sometimes necessary. See http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15
I would leave it as it is, but just for the sake of discussion, and depending on what parts of the code are 'untouchable' you could define a functor that takes a pField and initialize after the variable is created in the same scope:
class FFX_t {
FFX_t( FIELD * pField ) : field_(pField) {}
int operator()( int index ) {
return field_->GetValue( index );
}
private:
FIELD *field_;
};
// usage:
void f() {
FIELD * pField = //...
FFX_t FFX(pField); // added after pField construction
// ...
int a = FFX(5);
}
But I insist in that changing working code for the sake of it when it will not really add any value is useless.