C++ expected type specifier error - c++

I am trying to write a wrapper function to figure out who is calling a specific function. So in .h file I added the following: (and implementation in the .cc file)
extern int foo(/*some arguments*/);
extern void call_log(const char*file,const char*function,const int line,const char*args);
#define foo(...) (call_log(__FILE__, __FUNCTION__, __LINE__, "" #__VA_ARGS__), foo(__VA_ARGS__))
However, I get the following error:
error: expected a type specifier
(call_log(__FILE__, __FUNCTION__, __LINE__, "" #__VA_ARGS__),foo(__VA_ARGS__)
Assume that the foo function is called with some parameters and returns an int.
the compiler is gcc 3.4
Thanks
EDIT
removed "." and extra spaced, yet problem still there. Can anyone see what can cause it. Also notice that I am using variadic macros -- supported by my compiler (c99)
Edit 2
Just to get the claims about my illegal use of some c/c++ constructs. The following code below works, and I am trying to adapt it to my current (above function)
#include <stdio.h>
int funcA( int a, int b ){ return a+b; }
// instrumentation
void call_log(const char*file,const char*function,const int line,const char*args){
printf("file:%s line: %i function: %s args: %s\n",file,line,function,args);
}
#define funcA(...) \
(call_log(__FILE__, __FUNCTION__, __LINE__, "" #__VA_ARGS__), funcA(__VA_ARGS__))
// testing
void funcB()
{
funcA(7,8);
}
int main(void){
int x = funcA(1,2)+
funcA(3,4);
printf( "x: %i (==10)\n", x );
funcA(5,6);
funcB();
}
Edit 3
As litb pointed out, the problem is, in fact, due to macro substitutions. I also noticed that foo is not only a function call but also used as ptr->foo[] in some cases. Any ides how to resolve this sort of issues, without breaking more code

The best way to find out what's wrong would be to make the compiler show the preprocessed code. You can then easier spot the problem in the offending line.

If I'm not mistaken I believe you have a number of syntax errors in the definition and declaration of call_log.
In the definition I am pretty sure you need a space between the const char* and the variable name. ie...
extern void call_log(const char* file,const char* function,const int line,const char* args);
In addition, in the declaration, I don't think you can append #__VA_ARGS__ to "" in the manner you are doing. The macro will resolved this as:
(call_log(file_name, function_name, line_#, "" arg1, arg2...), foo(args[])
which is not a valid function call. On a side-note you are also missing a semicolon after the macro definition.
Finally, I do not see a reference to foo(args) in your macro definition; It's possible I'm missing some context but you may wish to look at that as well.
Hope this helps...
CJ

Related

Resharper C++ and Plog logger

I am using Plog in my project for logging. I also use resharper c++.
There are several macros used for logging that make it less verbose. One of the macros always gets marked as an issue with Resharper but I don't know why.
The macro is LOGD which expands to
if (!plog::get<0>() || !plog::get<0>()-
>checkSeverity(plog::debug)) {;} else (*plog::get<0>()) +=
plog::Record(plog::debug, __FUNCTION__, 151, "",
__if_exists(this) { this } __if_not_exists(this) { 0 }) <<
"Message";
The warning points to the usage of "this" as it expects an identifier.
The method it is calling has a signature of:
Record(Severity severity, const char* func, size_t line, const char* file, const void* object)
: m_severity(severity), m_tid(util::gettid()), m_object(object), m_line(line), m_func(func), m_file(file)
Does anyone have experience with this an know how to modify the macro so it does not complain?
I've filed RSCPP-22423, we'll try to fix this in one of the 2018.2 EAP builds. Until then, you can redefine the PLOG_GET_THIS macro for ReSharper C++ like this:
#include <plog/Log.h>
#if defined(__RESHARPER__)
#define PLOG_GET_THIS() reinterpret_cast<void*>(0)
#endif
Or similarly update the original definition of PLOG_GET_THIS (it already checks for the similar __INTELLISENSE__ macro to determine if __if_exists can be used).

C++: cleanest practice to write an empty function body [duplicate]

I have a cross platform application and in a few of my functions not all the values passed to functions are utilised. Hence I get a warning from GCC telling me that there are unused variables.
What would be the best way of coding around the warning?
An #ifdef around the function?
#ifdef _MSC_VER
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal qrLeft, qreal qrTop, qreal qrWidth, qreal qrHeight)
#else
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal /*qrLeft*/, qreal /*qrTop*/, qreal /*qrWidth*/, qreal /*qrHeight*/)
#endif
{
This is so ugly but seems like the way the compiler would prefer.
Or do I assign zero to the variable at the end of the function? (which I hate because it's altering something in the program flow to silence a compiler warning).
Is there a correct way?
You can put it in "(void)var;" expression (does nothing) so that a compiler sees it is used. This is portable between compilers.
E.g.
void foo(int param1, int param2)
{
(void)param2;
bar(param1);
}
Or,
#define UNUSED(expr) do { (void)(expr); } while (0)
...
void foo(int param1, int param2)
{
UNUSED(param2);
bar(param1);
}
In GCC and Clang you can use the __attribute__((unused)) preprocessor directive to achieve your goal.
For example:
int foo (__attribute__((unused)) int bar) {
return 0;
}
C++17 now provides the [[maybe_unused]] attribute.
http://en.cppreference.com/w/cpp/language/attributes
Quite nice and standard.
C++17 Update
In C++17 we gain the attribute [[maybe_unused]] which is covered in [dcl.attr.unused]
The attribute-token maybe_unused indicates that a name or entity is possibly intentionally unused. It shall
appear at most once in each attribute-list and no attribute-argument-clause shall be present.
...
Example:
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
[[maybe_unused]] bool thing2) {
[[maybe_unused]] bool b = thing1 && thing2;
assert(b);
}
Implementations should not warn that b is unused, whether or not NDEBUG is defined. —end example ]
For the following example:
int foo ( int bar) {
bool unused_bool ;
return 0;
}
Both clang and gcc generate a diagnostic using -Wall -Wextra for both bar and unused_bool (See it live).
While adding [[maybe_unused]] silences the diagnostics:
int foo ([[maybe_unused]] int bar) {
[[maybe_unused]] bool unused_bool ;
return 0;
}
see it live.
Before C++17
In C++11 an alternative form of the UNUSED macro could be formed using a lambda expression(via Ben Deane) with an capture of the unused variable:
#define UNUSED(x) [&x]{}()
The immediate invocation of the lambda expression should be optimized away, given the following example:
int foo (int bar) {
UNUSED(bar) ;
return 0;
}
we can see in godbolt that the call is optimized away:
foo(int):
xorl %eax, %eax
ret
Your current solution is best - comment out the parameter name if you don't use it. That applies to all compilers, so you don't have to use the pre-processor to do it specially for GCC.
An even cleaner way is to just comment out variable names:
int main(int /* argc */, char const** /* argv */) {
return 0;
}
gcc doesn't flag these warnings by default. This warning must have been turned on either explicitly by passing -Wunused-parameter to the compiler or implicitly by passing -Wall -Wextra (or possibly some other combination of flags).
Unused parameter warnings can simply be suppressed by passing -Wno-unused-parameter to the compiler, but note that this disabling flag must come after any possible enabling flags for this warning in the compiler command line, so that it can take effect.
A coworker just pointed me to this nice little macro here
For ease I'll include the macro below.
#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*#unused#*/ x
#else
# define UNUSED(x) x
#endif
void dcc_mon_siginfo_handler(int UNUSED(whatsig))
macro-less and portable way to declare one or more parameters as unused:
template <typename... Args> inline void unused(Args&&...) {}
int main(int argc, char* argv[])
{
unused(argc, argv);
return 0;
}
Using preprocessor directives is considered evil most of the time. Ideally you want to avoid them like the Pest. Remember that making the compiler understand your code is easy, allowing other programmers to understand your code is much harder. A few dozen cases like this here and there makes it very hard to read for yourself later or for others right now.
One way might be to put your parameters together into some sort of argument class. You could then use only a subset of the variables (equivalent to your assigning 0 really) or having different specializations of that argument class for each platform. This might however not be worth it, you need to analyze whether it would fit.
If you can read impossible templates, you might find advanced tips in the "Exceptional C++" book. If the people who would read your code could get their skillset to encompass the crazy stuff taught in that book, then you would have beautiful code which can also be easily read. The compiler would also be well aware of what you are doing (instead of hiding everything by preprocessing)
I have seen this instead of the (void)param2 way of silencing the warning:
void foo(int param1, int param2)
{
std::ignore = param2;
bar(param1);
}
Looks like this was added in C++11
Lol! I dont think there is another question on SO that reveal all the heretics corrupted by Chaos better that this one!
With all due respect to C++17 there is a clear guideline in C++ Core Guidelines. AFAIR, back in 2009 this option was available as well as today. And if somebody says it is considered as a bug in Doxygen then there is a bug in Doxygen
First off the warning is generated by the variable definition in the source file not the header file. The header can stay pristine and should, since you might be using something like doxygen to generate the API-documentation.
I will assume that you have completely different implementation in source files. In these cases you can either comment out the offending parameter or just write the parameter.
Example:
func(int a, int b)
{
b;
foo(a);
}
This might seem cryptic, so defined a macro like UNUSED. The way MFC did it is:
#ifdef _DEBUG
#define UNUSED(x)
#else
#define UNUSED(x) x
#endif
Like this you see the warning still in debug builds, might be helpful.
Is it not safe to always comment out parameter names? If it's not you can do something like
#ifdef _MSC_VER
# define P_(n) n
#else
# define P_(n)
#endif
void ProcessOps::sendToExternalApp(
QString sAppName, QString sImagePath,
qreal P_(qrLeft), qreal P_(qrTop), qreal P_(qrWidth), qreal P_(qrHeight))
It's a bit less ugly.
Using an UNREFERENCED_PARAMETER(p) could work. I know it is defined in WinNT.h for Windows systems and can easily be defined for gcc as well (if it doesn't already have it).
UNREFERENCED PARAMETER(p) is defined as
#define UNREFERENCED_PARAMETER(P) (P)
in WinNT.h.
Use compiler's flag, e.g. flag for GCC:
-Wno-unused-variable
In C++11, this is the solution I'm using:
template<typename... Ts> inline void Unreferenced(Ts&&...) {}
int Foo(int bar)
{
Unreferenced(bar);
return 0;
}
int Foo2(int bar1, int bar2)
{
Unreferenced(bar1, bar2);
return 0;
}
Verified to be portable (at least on modern msvc, clang and gcc) and not producing extra code when optimizations are enabled.
With no optimization, the extra function call is performed and references to the parameters are copied to the stack, but there are no macros involved.
If the extra code is an issue, you can use this declaration instead:
(decltype(Unreferenced(bar1, bar2)))0;
but at that point, a macro provides better readability:
#define UNREFERENCED(...) { (decltype(Unreferenced(__VA_ARGS__)))0; }
This works well but requires C++11
template <typename ...Args>
void unused(Args&& ...args)
{
(void)(sizeof...(args));
}
You can use __unused to tell the compiler that variable might not be used.
- (void)myMethod:(__unused NSObject *)theObject
{
// there will be no warning about `theObject`, because you wrote `__unused`
__unused int theInt = 0;
// there will be no warning, but you are still able to use `theInt` in the future
}
I found most of the presented answers work for local unused variable only, and will cause compile error for unused static global variable.
Another macro needed to suppress the warning of unused static global variable.
template <typename T>
const T* UNUSED_VARIABLE(const T& dummy) {
return &dummy;
}
#define UNUSED_GLOBAL_VARIABLE(x) namespace {\
const auto dummy = UNUSED_VARIABLE(x);\
}
static int a = 0;
UNUSED_GLOBAL_VARIABLE(a);
int main ()
{
int b = 3;
UNUSED_VARIABLE(b);
return 0;
}
This works because no warning will be reported for non-static global variable in anonymous namespace.
C++ 11 is required though
g++ -Wall -O3 -std=c++11 test.cpp
void func(void *aux UNUSED)
{
return;
}
smth like that, in that case if u dont use aux it wont warn u
I don't see your problem with the warning. Document it in the method/function header that compiler xy will issue a (correct) warning here, but that theses variables are needed for platform z.
The warning is correct, no need to turn it off. It does not invalidate the program - but it should be documented, that there is a reason.

#define equivalent in a namespace [duplicate]

My application uses another output than the standard output for logging information, which is why I wrote my own Log(), Error(), Panic() and Assert() functions. To organize things nicely, I enclose all the debugging stuff in a Debug namespace.
It would make more sense for the Assert() function to also provide a source file and line number, which is only possible using the __LINE__ and __FILE__ macros. However, it is pretty unpleasant, inefficient etc... to always have to specify these two parameters.
So this is how my code would look like:
namespace Debug {
void Assert (int condition, std::string message, std::string file, int line);
}
My question is, is it possible to place a macro which includes those two parameters inside the Debug namespace? Like this:
namespace Debug {
void Assert_ (int condition, std::string message, std::string file, int line);
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
// Output: Assertion failed on line 10 in file test.cpp:
// Some_condition should be true
Is this valid c++? If not, is there any way of making this work?
#define is a preprocessor directive. The macros are being replaced before anything else apart from removing comments (which means, before compilation). So at the time macros are replaced, the compiler knows nothing about your namespaces.
As other people state, in your case it will be fine. However, This is how you can get problems:
namespace A
{
void Assert_ (int condition, std::string message, std::string file, int line)
{
std::cout << "A";
}
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
namespace B
{
void Assert_ (int condition)
{
std::cout << "B";
}
#define Assert(a,b) Assert_(a)
}
int main(int argc, char *argv[])
{
A::Assert(0,"asdasd");
B::Assert(0,"asdasd");
}
So while it looks like the defines are "in the namespaces", they are not, and the last #define will be always be used, which in this case will lead to a compile-time error, because the code in main will be replaced by:
A::Assert(0);
B::Assert(0);
instead of
A::Assert(0,"asdasd", _FILE_, _LINE_);
B::Assert(0);
No, the preprocessor doesn't care about namespaces at all. In fact, the preprocessor runs, at least conceptually, before the compiler sees anything.
For myself, I just do a standard ASSERT macro, and expect that no "sane namespace" has something called ASSERT. Problem solved. Should I require a library that has an ASSERT of its own then I can still decide how to deal with this; however, the only library that I'm currently using with its own "assert" calls it BOOST_ASSERT or something like that...
namespace Debug
{
void Assert_(int condition, std::string message, std::string file, int line);
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
This specific usage would do exactly what you want, but the Assert macro is in no way part of the Debug namespace... it's exactly as if you'd done:
namespace Debug
{
void Assert_(int condition, std::string message, std::string file, int line);
}
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
Here, the substitution works not because Assert was in the Debug namespace (it's not in your code or this code, and the preprocessor has no clue what namespaces are about) - it works because Assert is recognised as an identifier for a macro, the substitution of Assert_ is made, then later the compiler proper happens to find there's a Debug::Assert_
So, say you have somewhere later in your translation unit you have some completely unrelated code:
my_object.Assert(my_functor);
The macro substituion will still kick in to produce a compile-time error saying you have the wrong number of arguments to a macro. Say the unrelated code was instead:
my_object.Assert(my_functor, "some text");
Then that would be replaced with:
my_object.Assert_(my_functor, "some text", __FILE__, __LINE__);
(Separately, it's standard practice not to use lower case letters in preprocessor macro names).
You can try __PRETTY_FUNCTION __ macro to print all the namespaces including function arguments.
Yes, and your macro would expand to exactly what you expect.
Debug::Assert (some_condition, "Some_condition should be true");
would be replaced by
Debug::Assert_(some_condition, "Some_condition should be true", __FILE__, __LINE__)

Is it possible to place a macro in a namespace in c++?

My application uses another output than the standard output for logging information, which is why I wrote my own Log(), Error(), Panic() and Assert() functions. To organize things nicely, I enclose all the debugging stuff in a Debug namespace.
It would make more sense for the Assert() function to also provide a source file and line number, which is only possible using the __LINE__ and __FILE__ macros. However, it is pretty unpleasant, inefficient etc... to always have to specify these two parameters.
So this is how my code would look like:
namespace Debug {
void Assert (int condition, std::string message, std::string file, int line);
}
My question is, is it possible to place a macro which includes those two parameters inside the Debug namespace? Like this:
namespace Debug {
void Assert_ (int condition, std::string message, std::string file, int line);
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
// Output: Assertion failed on line 10 in file test.cpp:
// Some_condition should be true
Is this valid c++? If not, is there any way of making this work?
#define is a preprocessor directive. The macros are being replaced before anything else apart from removing comments (which means, before compilation). So at the time macros are replaced, the compiler knows nothing about your namespaces.
As other people state, in your case it will be fine. However, This is how you can get problems:
namespace A
{
void Assert_ (int condition, std::string message, std::string file, int line)
{
std::cout << "A";
}
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
namespace B
{
void Assert_ (int condition)
{
std::cout << "B";
}
#define Assert(a,b) Assert_(a)
}
int main(int argc, char *argv[])
{
A::Assert(0,"asdasd");
B::Assert(0,"asdasd");
}
So while it looks like the defines are "in the namespaces", they are not, and the last #define will be always be used, which in this case will lead to a compile-time error, because the code in main will be replaced by:
A::Assert(0);
B::Assert(0);
instead of
A::Assert(0,"asdasd", _FILE_, _LINE_);
B::Assert(0);
No, the preprocessor doesn't care about namespaces at all. In fact, the preprocessor runs, at least conceptually, before the compiler sees anything.
For myself, I just do a standard ASSERT macro, and expect that no "sane namespace" has something called ASSERT. Problem solved. Should I require a library that has an ASSERT of its own then I can still decide how to deal with this; however, the only library that I'm currently using with its own "assert" calls it BOOST_ASSERT or something like that...
namespace Debug
{
void Assert_(int condition, std::string message, std::string file, int line);
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
This specific usage would do exactly what you want, but the Assert macro is in no way part of the Debug namespace... it's exactly as if you'd done:
namespace Debug
{
void Assert_(int condition, std::string message, std::string file, int line);
}
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
Here, the substitution works not because Assert was in the Debug namespace (it's not in your code or this code, and the preprocessor has no clue what namespaces are about) - it works because Assert is recognised as an identifier for a macro, the substitution of Assert_ is made, then later the compiler proper happens to find there's a Debug::Assert_
So, say you have somewhere later in your translation unit you have some completely unrelated code:
my_object.Assert(my_functor);
The macro substituion will still kick in to produce a compile-time error saying you have the wrong number of arguments to a macro. Say the unrelated code was instead:
my_object.Assert(my_functor, "some text");
Then that would be replaced with:
my_object.Assert_(my_functor, "some text", __FILE__, __LINE__);
(Separately, it's standard practice not to use lower case letters in preprocessor macro names).
You can try __PRETTY_FUNCTION __ macro to print all the namespaces including function arguments.
Yes, and your macro would expand to exactly what you expect.
Debug::Assert (some_condition, "Some_condition should be true");
would be replaced by
Debug::Assert_(some_condition, "Some_condition should be true", __FILE__, __LINE__)

How do I best silence a warning about unused variables?

I have a cross platform application and in a few of my functions not all the values passed to functions are utilised. Hence I get a warning from GCC telling me that there are unused variables.
What would be the best way of coding around the warning?
An #ifdef around the function?
#ifdef _MSC_VER
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal qrLeft, qreal qrTop, qreal qrWidth, qreal qrHeight)
#else
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal /*qrLeft*/, qreal /*qrTop*/, qreal /*qrWidth*/, qreal /*qrHeight*/)
#endif
{
This is so ugly but seems like the way the compiler would prefer.
Or do I assign zero to the variable at the end of the function? (which I hate because it's altering something in the program flow to silence a compiler warning).
Is there a correct way?
You can put it in "(void)var;" expression (does nothing) so that a compiler sees it is used. This is portable between compilers.
E.g.
void foo(int param1, int param2)
{
(void)param2;
bar(param1);
}
Or,
#define UNUSED(expr) do { (void)(expr); } while (0)
...
void foo(int param1, int param2)
{
UNUSED(param2);
bar(param1);
}
In GCC and Clang you can use the __attribute__((unused)) preprocessor directive to achieve your goal.
For example:
int foo (__attribute__((unused)) int bar) {
return 0;
}
C++17 now provides the [[maybe_unused]] attribute.
http://en.cppreference.com/w/cpp/language/attributes
Quite nice and standard.
C++17 Update
In C++17 we gain the attribute [[maybe_unused]] which is covered in [dcl.attr.unused]
The attribute-token maybe_unused indicates that a name or entity is possibly intentionally unused. It shall
appear at most once in each attribute-list and no attribute-argument-clause shall be present.
...
Example:
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
[[maybe_unused]] bool thing2) {
[[maybe_unused]] bool b = thing1 && thing2;
assert(b);
}
Implementations should not warn that b is unused, whether or not NDEBUG is defined. —end example ]
For the following example:
int foo ( int bar) {
bool unused_bool ;
return 0;
}
Both clang and gcc generate a diagnostic using -Wall -Wextra for both bar and unused_bool (See it live).
While adding [[maybe_unused]] silences the diagnostics:
int foo ([[maybe_unused]] int bar) {
[[maybe_unused]] bool unused_bool ;
return 0;
}
see it live.
Before C++17
In C++11 an alternative form of the UNUSED macro could be formed using a lambda expression(via Ben Deane) with an capture of the unused variable:
#define UNUSED(x) [&x]{}()
The immediate invocation of the lambda expression should be optimized away, given the following example:
int foo (int bar) {
UNUSED(bar) ;
return 0;
}
we can see in godbolt that the call is optimized away:
foo(int):
xorl %eax, %eax
ret
Your current solution is best - comment out the parameter name if you don't use it. That applies to all compilers, so you don't have to use the pre-processor to do it specially for GCC.
An even cleaner way is to just comment out variable names:
int main(int /* argc */, char const** /* argv */) {
return 0;
}
gcc doesn't flag these warnings by default. This warning must have been turned on either explicitly by passing -Wunused-parameter to the compiler or implicitly by passing -Wall -Wextra (or possibly some other combination of flags).
Unused parameter warnings can simply be suppressed by passing -Wno-unused-parameter to the compiler, but note that this disabling flag must come after any possible enabling flags for this warning in the compiler command line, so that it can take effect.
A coworker just pointed me to this nice little macro here
For ease I'll include the macro below.
#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*#unused#*/ x
#else
# define UNUSED(x) x
#endif
void dcc_mon_siginfo_handler(int UNUSED(whatsig))
macro-less and portable way to declare one or more parameters as unused:
template <typename... Args> inline void unused(Args&&...) {}
int main(int argc, char* argv[])
{
unused(argc, argv);
return 0;
}
Using preprocessor directives is considered evil most of the time. Ideally you want to avoid them like the Pest. Remember that making the compiler understand your code is easy, allowing other programmers to understand your code is much harder. A few dozen cases like this here and there makes it very hard to read for yourself later or for others right now.
One way might be to put your parameters together into some sort of argument class. You could then use only a subset of the variables (equivalent to your assigning 0 really) or having different specializations of that argument class for each platform. This might however not be worth it, you need to analyze whether it would fit.
If you can read impossible templates, you might find advanced tips in the "Exceptional C++" book. If the people who would read your code could get their skillset to encompass the crazy stuff taught in that book, then you would have beautiful code which can also be easily read. The compiler would also be well aware of what you are doing (instead of hiding everything by preprocessing)
I have seen this instead of the (void)param2 way of silencing the warning:
void foo(int param1, int param2)
{
std::ignore = param2;
bar(param1);
}
Looks like this was added in C++11
Lol! I dont think there is another question on SO that reveal all the heretics corrupted by Chaos better that this one!
With all due respect to C++17 there is a clear guideline in C++ Core Guidelines. AFAIR, back in 2009 this option was available as well as today. And if somebody says it is considered as a bug in Doxygen then there is a bug in Doxygen
First off the warning is generated by the variable definition in the source file not the header file. The header can stay pristine and should, since you might be using something like doxygen to generate the API-documentation.
I will assume that you have completely different implementation in source files. In these cases you can either comment out the offending parameter or just write the parameter.
Example:
func(int a, int b)
{
b;
foo(a);
}
This might seem cryptic, so defined a macro like UNUSED. The way MFC did it is:
#ifdef _DEBUG
#define UNUSED(x)
#else
#define UNUSED(x) x
#endif
Like this you see the warning still in debug builds, might be helpful.
Is it not safe to always comment out parameter names? If it's not you can do something like
#ifdef _MSC_VER
# define P_(n) n
#else
# define P_(n)
#endif
void ProcessOps::sendToExternalApp(
QString sAppName, QString sImagePath,
qreal P_(qrLeft), qreal P_(qrTop), qreal P_(qrWidth), qreal P_(qrHeight))
It's a bit less ugly.
Using an UNREFERENCED_PARAMETER(p) could work. I know it is defined in WinNT.h for Windows systems and can easily be defined for gcc as well (if it doesn't already have it).
UNREFERENCED PARAMETER(p) is defined as
#define UNREFERENCED_PARAMETER(P) (P)
in WinNT.h.
Use compiler's flag, e.g. flag for GCC:
-Wno-unused-variable
In C++11, this is the solution I'm using:
template<typename... Ts> inline void Unreferenced(Ts&&...) {}
int Foo(int bar)
{
Unreferenced(bar);
return 0;
}
int Foo2(int bar1, int bar2)
{
Unreferenced(bar1, bar2);
return 0;
}
Verified to be portable (at least on modern msvc, clang and gcc) and not producing extra code when optimizations are enabled.
With no optimization, the extra function call is performed and references to the parameters are copied to the stack, but there are no macros involved.
If the extra code is an issue, you can use this declaration instead:
(decltype(Unreferenced(bar1, bar2)))0;
but at that point, a macro provides better readability:
#define UNREFERENCED(...) { (decltype(Unreferenced(__VA_ARGS__)))0; }
This works well but requires C++11
template <typename ...Args>
void unused(Args&& ...args)
{
(void)(sizeof...(args));
}
You can use __unused to tell the compiler that variable might not be used.
- (void)myMethod:(__unused NSObject *)theObject
{
// there will be no warning about `theObject`, because you wrote `__unused`
__unused int theInt = 0;
// there will be no warning, but you are still able to use `theInt` in the future
}
I found most of the presented answers work for local unused variable only, and will cause compile error for unused static global variable.
Another macro needed to suppress the warning of unused static global variable.
template <typename T>
const T* UNUSED_VARIABLE(const T& dummy) {
return &dummy;
}
#define UNUSED_GLOBAL_VARIABLE(x) namespace {\
const auto dummy = UNUSED_VARIABLE(x);\
}
static int a = 0;
UNUSED_GLOBAL_VARIABLE(a);
int main ()
{
int b = 3;
UNUSED_VARIABLE(b);
return 0;
}
This works because no warning will be reported for non-static global variable in anonymous namespace.
C++ 11 is required though
g++ -Wall -O3 -std=c++11 test.cpp
void func(void *aux UNUSED)
{
return;
}
smth like that, in that case if u dont use aux it wont warn u
I don't see your problem with the warning. Document it in the method/function header that compiler xy will issue a (correct) warning here, but that theses variables are needed for platform z.
The warning is correct, no need to turn it off. It does not invalidate the program - but it should be documented, that there is a reason.