I am trying to define a macro in the format
#define SUM(x,y) ({log_var = x; log_var += y;})
void main(void)
{
unsigned int log_var;
SUM(10,20);
}
Compilation of the same by ARMCC throws an error "Expected an expression" but compilation with GCC doesn't throw the error.
Is it the syntax ({<statements>}); is not allowed in ARMCC or is there any other reason for the same ?
The same disappears when the parentheses is removed. i.e {<statements>}
If you want to have a multi-statement macro body, the usual way is to have a one-iteration do while loop:
#define SUM(x,y) do {log_var = x; log_var += y;} while (0)
Related
For instance:
Bool NullFunc(const struct timespec *when, const char *who)
{
return TRUE;
}
In C++ I was able to put a /*...*/ comment around the parameters. But not in C of course, where it gives me the error:
error: parameter name omitted
I usually write a macro like this:
#define UNUSED(x) (void)(x)
You can use this macro for all your unused parameters. (Note that this works on any compiler.)
For example:
void f(int x) {
UNUSED(x);
...
}
In GCC, you can label the parameter with the unused attribute.
This attribute, attached to a variable, means that the variable is
meant to be possibly unused. GCC will not produce a warning for this
variable.
In practice this is accomplished by putting __attribute__ ((unused)) just before the parameter. For example:
void foo(workerid_t workerId) { }
becomes
void foo(__attribute__((unused)) workerid_t workerId) { }
You can use GCC or Clang's unused attribute. However, I use these macros in a header to avoid having GCC specific attributes all over the source, also having __attribute__ everywhere is a bit verbose/ugly.
#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define UNUSED(x) UNUSED_ ## x
#endif
#ifdef __GNUC__
# define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
# define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif
Then you can do...
void foo(int UNUSED(bar)) { ... }
I prefer this because you get an error if you try use bar in the code anywhere, so you can't leave the attribute in by mistake.
And for functions...
static void UNUSED_FUNCTION(foo)(int bar) { ... }
Note 1):
As far as I know, MSVC doesn't have an equivalent to __attribute__((__unused__)).
Note 2):
The UNUSED macro won't work for arguments which contain parenthesis,
so if you have an argument like float (*coords)[3] you can't do,
float UNUSED((*coords)[3]) or float (*UNUSED(coords))[3]. This is the only downside to the UNUSED macro I found so far, and in these cases I fall back to (void)coords;.
Seeing that this is marked as gcc you can use the command line switch Wno-unused-parameter.
For example:
gcc -Wno-unused-parameter test.c
Of course this effects the whole file (and maybe project depending where you set the switch) but you don't have to change any code.
With GCC with the unused attribute:
int foo (__attribute__((unused)) int bar) {
return 0;
}
A gcc/g++ specific way to suppress the unused parameter warning for a block of source code is to enclose it with the following pragma statements:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop
Since C++ 17, the [[maybe_unused]] attribute can be used to suppress warnings about unused parameters.
Based on the OP's example code:
Bool NullFunc([[maybe_unused]] const struct timespec *when, [[maybe_unused]] const char *who)
{
return TRUE;
}
I got the same problem. I used a third-part library. When I compile this library, the compiler (gcc/clang) will complain about unused variables.
Like this
test.cpp:29:11: warning: variable 'magic' set but not used [-Wunused-but-set-variable]
short magic[] = {
test.cpp:84:17: warning: unused variable 'before_write' [-Wunused-variable]
int64_t before_write = Thread::currentTimeMillis();
So the solution is pretty clear. Adding -Wno-unused as gcc/clang CFLAG will suppress all "unused" warnings, even thought you have -Wall set.
In this way, you DO NOT NEED to change any code.
Labelling the attribute is ideal way. MACRO leads to sometime confusion.
and by using void(x),we are adding an overhead in processing.
If not using input argument, use
void foo(int __attribute__((unused))key)
{
}
If not using the variable defined inside the function
void foo(int key)
{
int hash = 0;
int bkt __attribute__((unused)) = 0;
api_call(x, hash, bkt);
}
Now later using the hash variable for your logic but doesn’t need bkt. define bkt as unused, otherwise compiler says'bkt set bt not used".
NOTE: This is just to suppress the warning not for optimization.
In MSVC to suppress a particular warning it is enough to specify the it's number to compiler as /wd#. My CMakeLists.txt contains such the block:
If (MSVC)
Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
Add_definitions (-Wall -W -pedantic)
Else ()
Message ("Unknown compiler")
Endif ()
Now I can not say what exactly /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127 mean, because I do not pay any attention to MSVC for three years, but they suppress superpedantic warnings that does not influence the result.
I've seen this style being used:
if (when || who || format || data || len);
For the record, I like Job's answer, but I'm curious about a solution just using the variable name by itself in a "do-nothing" statement:
void foo(int x) {
x; /* unused */
...
}
Sure, this has drawbacks; for instance, without the "unused" note it looks like a mistake rather than an intentional line of code.
The benefit is that no DEFINE is needed and it gets rid of the warning.
I wrote the following C code (according to the C99 standard) and it ran with no problems:
#include <stdio.h>
#ifdef _WIN32
printf("Running on Windows");
#endif
void test(int x);
int main() {
return 0;
}
but adding else caused so much errors (around 12) what's the problem with the new code:
#ifdef _WIN32
printf("Running on Windows");
#else
printf("Running on Windows");
#endif
Some of the errors:
error: expected parameter declarator
expected ')'
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
error: conflicting types for 'printf'
When you use conditional compilation the preprocessor adds code to your program before the compile step.
So, if the symbol _WIN32 exists, then you are effectively saying
printf("Running on Windows");
void test(int x);
int main() {
return 0;
}
and that is syntactically incorrect because you have executable code (a call to printf) outside all functions.
If you didn't have a problem before you added the '#else' then that was because the symbol _WIN32 doesn't exist and the preprocessor wasn't adding the printf statement to your code.
Given the following code written according to the C99 standard:
#define LOW 1
#define MEDIUM 2
#define HIGH 3
#define LOGGING_LEVEL HIGH
#if LOGGING_LEVEL >= MEDIUM
#define LOG_MEDIUM(message) printf(message)
#else
#define LOG_MEDIUM(message) ((void)0)
#endif
void load_configuration() {
//...
LOG_MEDIUM("Configuration loaded\n");
}
what's the purpose of ((void)0) I searched the web a lot but nothing found regarding this.
Plus, why didn't we wrote ; after using printf(message)
The void-cast fixes a compiler warning. Here's an analogous testcase:
int main(void)
{
0; // generates "foo.c:3:2: warning: statement with no effect"
(void)0;
return 0;
}
and (using a script to add gcc's warning flags) you see a warning for the line without a cast:
$ gcc-stricter -c foo.c
foo.c: In function ‘main’:
foo.c:3:2: warning: statement with no effect [-Wunused-value]
0;
^
The extra parentheses and lack of semicolon allow the macro's result to be used interchangeably with the printf.
Main idea is to exclude all LOG_MEDIUM if the criteria was not meet.
After compilation those calls will not affect functionality.
I don't understand why this works:
/* gcc range extension */
__extension__ static int fn(int n)
{
switch (n) {
case 0: return 0;
case 1 ... 1000: return 1;
default: return -1;
}
}
But this does not:
/* gcc typeof extension */
__extension__ static void fn(int n)
{
typeof(n) a = n;
printf("%d\n", a);
}
gcc returns:
demo.c:14: warning: implicit declaration of function ‘typeof’
demo.c:14: warning: nested extern declaration of ‘typeof’
demo.c:14: error: expected ‘;’ before ‘a’
demo.c:16: error: ‘a’ undeclared (first use in this function)
demo.c:16: error: (Each undeclared identifier is reported only once
demo.c:16: error: for each function it appears in.)
I know I can compile with -std=gnu99 to avoid the error but the first one works with -std=c99 and uses also an extension
Non-ANSI compatible keywords are not ever reenabled by __extension__ (the only effect of __extension__ is warning suppression for -pedantic). Use __typeof__ if you want to compile in ANSI mode.
If you are writing a header file that must work when included in ISO C programs, write __typeof__ instead of typeof.
Refer to this link for a more elaborate description and the possible fixes.
Note: __extension__ has no effect aside from suppressing the warnings when using ANSI C -pedantic mode.
So something like this:
/* gcc typeof extension */
__extension__ static void fn(int n)
{
__typeof__(n) a = n;
printf("%d\n", a);
}
For instance:
Bool NullFunc(const struct timespec *when, const char *who)
{
return TRUE;
}
In C++ I was able to put a /*...*/ comment around the parameters. But not in C of course, where it gives me the error:
error: parameter name omitted
I usually write a macro like this:
#define UNUSED(x) (void)(x)
You can use this macro for all your unused parameters. (Note that this works on any compiler.)
For example:
void f(int x) {
UNUSED(x);
...
}
In GCC, you can label the parameter with the unused attribute.
This attribute, attached to a variable, means that the variable is
meant to be possibly unused. GCC will not produce a warning for this
variable.
In practice this is accomplished by putting __attribute__ ((unused)) just before the parameter. For example:
void foo(workerid_t workerId) { }
becomes
void foo(__attribute__((unused)) workerid_t workerId) { }
You can use GCC or Clang's unused attribute. However, I use these macros in a header to avoid having GCC specific attributes all over the source, also having __attribute__ everywhere is a bit verbose/ugly.
#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define UNUSED(x) UNUSED_ ## x
#endif
#ifdef __GNUC__
# define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
# define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif
Then you can do...
void foo(int UNUSED(bar)) { ... }
I prefer this because you get an error if you try use bar in the code anywhere, so you can't leave the attribute in by mistake.
And for functions...
static void UNUSED_FUNCTION(foo)(int bar) { ... }
Note 1):
As far as I know, MSVC doesn't have an equivalent to __attribute__((__unused__)).
Note 2):
The UNUSED macro won't work for arguments which contain parenthesis,
so if you have an argument like float (*coords)[3] you can't do,
float UNUSED((*coords)[3]) or float (*UNUSED(coords))[3]. This is the only downside to the UNUSED macro I found so far, and in these cases I fall back to (void)coords;.
Seeing that this is marked as gcc you can use the command line switch Wno-unused-parameter.
For example:
gcc -Wno-unused-parameter test.c
Of course this effects the whole file (and maybe project depending where you set the switch) but you don't have to change any code.
With GCC with the unused attribute:
int foo (__attribute__((unused)) int bar) {
return 0;
}
A gcc/g++ specific way to suppress the unused parameter warning for a block of source code is to enclose it with the following pragma statements:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop
Since C++ 17, the [[maybe_unused]] attribute can be used to suppress warnings about unused parameters.
Based on the OP's example code:
Bool NullFunc([[maybe_unused]] const struct timespec *when, [[maybe_unused]] const char *who)
{
return TRUE;
}
I got the same problem. I used a third-part library. When I compile this library, the compiler (gcc/clang) will complain about unused variables.
Like this
test.cpp:29:11: warning: variable 'magic' set but not used [-Wunused-but-set-variable]
short magic[] = {
test.cpp:84:17: warning: unused variable 'before_write' [-Wunused-variable]
int64_t before_write = Thread::currentTimeMillis();
So the solution is pretty clear. Adding -Wno-unused as gcc/clang CFLAG will suppress all "unused" warnings, even thought you have -Wall set.
In this way, you DO NOT NEED to change any code.
Labelling the attribute is ideal way. MACRO leads to sometime confusion.
and by using void(x),we are adding an overhead in processing.
If not using input argument, use
void foo(int __attribute__((unused))key)
{
}
If not using the variable defined inside the function
void foo(int key)
{
int hash = 0;
int bkt __attribute__((unused)) = 0;
api_call(x, hash, bkt);
}
Now later using the hash variable for your logic but doesn’t need bkt. define bkt as unused, otherwise compiler says'bkt set bt not used".
NOTE: This is just to suppress the warning not for optimization.
In MSVC to suppress a particular warning it is enough to specify the it's number to compiler as /wd#. My CMakeLists.txt contains such the block:
If (MSVC)
Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
Add_definitions (-Wall -W -pedantic)
Else ()
Message ("Unknown compiler")
Endif ()
Now I can not say what exactly /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127 mean, because I do not pay any attention to MSVC for three years, but they suppress superpedantic warnings that does not influence the result.
I've seen this style being used:
if (when || who || format || data || len);
For the record, I like Job's answer, but I'm curious about a solution just using the variable name by itself in a "do-nothing" statement:
void foo(int x) {
x; /* unused */
...
}
Sure, this has drawbacks; for instance, without the "unused" note it looks like a mistake rather than an intentional line of code.
The benefit is that no DEFINE is needed and it gets rid of the warning.