When implementing stubs etc. you want to avoid "unused variable" warnings. I've come across a few alternatives of UNUSED() macros over the years, but never one which either is proven to work for "all" compilers, or one which by standard is air tight.
Or are we stuck with #ifdef blocks for each build platform?
EDIT: Due to a number of answers with non c-compliant alternatives, I'd like to clarify that I'm looking for a definition which is valid for both C and C++, all flavours etc.
According to this answer by user GMan the typical way is to cast to void:
#define UNUSED(x) (void)(x)
but if x is marked as volatile that would enforce reading from the variable and thus have a side effect and so the actual way to almost guarantee a no-op and suppress the compiler warning is the following:
// use expression as sub-expression,
// then make type of full expression int, discard result
#define UNUSED(x) (void)(sizeof((x), 0))
In C++, just comment out the names.
void MyFunction(int /* name_of_arg1 */, float /* name_of_arg2*/)
{
...
}
The universal way is not to turn on warnings options that spam warnings for clearly-correct code. Any "unused variable" warning option that includes function arguments in its analysis is simply wrong and should be left off. Don't litter your code with ugliness to quiet broken compilers.
You might also try sending a bug report to the compiler maintainer/vendor.
Related
I have a macro which instantiates a global variable. And thus clang-tidy will correctly issue an "Initialization of ... with static storage duration may throw an exception which cannot be caught".
Can I disable this warning on a per-macro basis? Preferable inline where the macro is defined.
That is, let's say I have:
// header.h
#define UGLY_MACRO(X) SomeClass X(#X)
// source.cpp
UGLY_MACRO(SomeName); // clang-tidy complains here
And I want clang-tidy to stop complaining about this.
I want to be as specific as possible.
I only want to turn of this warning for this macro. I do not want to turn of the warning globally, then someone might add more of this kind of macros into the code unnoticed.
Also, I don’t want to add something (like a //NOLNT(...)) at every place where the macro is used, that would be too much of a hassle.
Or am I approaching this from the wrong direction? I have worked with pc-lint before, where this is possible.
I have the same problem. I have found two ways to do this, none of which are perfect, sadly.
Option 1 by using the --line-filter command-line argument for clang-tidy:
clang-tidy --line-filter='["name":"header.h"]' source.cpp
Notes:
Sadly this doesn't selectively work on one warning only, it disables all of them.
Unlike --filter-regex, this works even for macro expansion.
You can be more specific and specify the range of line numbers in header.h you want to disable the warnings for (see the help text for --line-filter)
Option 2 by wrapping the macro:
#define UGLY_MACRO_NOLINT(...) UGLY_MACRO(__VA_ARGS__) //NOLINT(...)
Notes:
Requires modifying your source code to use the nolint version
Does not work if UGLY_MACRO is multi-line
As far as I know this is not possible. The check in question (cert-err58-cpp) doesn't have configurable options which means it can't be disabled on a per-macro basis, only globally.
Save for modifying the check's source the only option you have here is // NOLINT(cert-err58-cpp) and // NOLINTNEXTLINE(cert-err58-cpp). The latter is a little easier to use for text search and replace as you only need to catch a newline followed by the macro name.
I'm developing an online judge system for programming contests. Since C/C++ inline assembly is not allowed in certain programming contests, I would like to add the same restriction to my system.
I would like to let GCC produce an error when compiling a C/C++ program containing inline assembly, so that any program containing inline assembly will be rejected. Is there a way to achieve that?
Note: disabling inline assembly is just for obeying the rules, not for security concerns.
Is there a way to disable inline assembler in GCC?
Yes there are a couple of methods; none useful for security, only guard-rails that could be worked around intentionally, but will stop people from accidentally using asm in places they didn't realize they shouldn't.
Turn off the asm keyword in the compiler (C only)
To do it in compilation phase, use the parameter -fno-asm. However, keep in mind that this will only affect asm for C, not C++. And not __asm__ or __asm for either language.
Documentation:
-fno-asm
Do not recognize "asm", "inline" or "typeof" as a keyword, so that code can use these words as identifiers. You can use the keywords "__asm__", "__inline__" and "__typeof__" instead. -ansi implies -fno-asm.
In C++ , this switch only affects the "typeof" keyword, since "asm" and "inline" are standard keywords. You may want to use the -fno-gnu-keywords flag instead, which has the same effect. In C99 mode (-std=c99 or -std=gnu99), this switch only affects the "asm" and "typeof" keywords, since "inline" is a standard keyword in ISO C99.
Define the keyword as a macro
You can use the parameters -Dasm=error -D__asm__=error -D__asm=error
Note that this construction is generic. What it does is to create macros. It works pretty much like a #define. The documentation says:
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a #define directive. In particular, the definition will be truncated by embedded newline characters.
...
So what it does is simply to change occurrences of asm, __asm, or __asm__ to error. This is done in the preprocessor phase. You don't have to use error. Just pick anything that will not compile.
Use a macro that fires during compilation
A way to solve it in compilation phase by using a macro, as suggested in comments by zwol, you can use -D'asm(...)=_Static_assert(0,"inline assembly not allowed")'. This will also solve the problem if there exist an identifier called error.
Note: This method requires -std=c11 or higher.
Using grep before using gcc
Yet another way that may be the solution to your problem is to just do a grep in the root of the source tree before compiling:
grep -nr "asm"
This will also catch __asm__ but it may give false positives, for instance is you have a string literal, identifier or comment containing the substring "asm". But in your case you could solve this problem by also forbidding any occurrence of that string anywhere in the source code. Just change the rules.
Possible unexpected problems
Note that disabling assembly can cause other problems. For instance, I could not use stdio.h with this option. It is common that system headers contains inline assembly code.
A way to cheat above methods
Aside from the trivial #undef __asm__, it is possible to execute strings as machine code. See this answer for an example: https://stackoverflow.com/a/18477070/6699433
A piece of the code from the link above:
/* our machine code */
char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
0x89,0x75,0xf0,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/* copy code to executable buffer */
void *buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
int i = ((int (*) (void))buf)();
The code above is only intended to give a quick idea of how to trick the rules OP has stated. It is not intended to be a good example of how to actually perform it in reality. Furthermore, the code is not mine. It is just a short code quote from the link I supplied. If you have ideas about how to improve it, then please comment on 4pie0:s original post instead.
I know that my question is similar to this one or this one, but I find that it is not really the same and, more, the second one has not an answer accepted, I decided to ask if it is correct to add preprocessor directives when a function-like macro is called?
In my case I have a function-like macro:
#define FUNC_MACRO(a, b) // do something with the variables
and somewhere in the code I call it with specific difference if some other macro is defined:
// ...
FUNC_MACRO(aVal
#ifdef ANOTHER_MACRO
+ offset
#endif // ANOTHER_MACRO
, bVal);
// ...
I tested on my machine (linux, with gcc 4.8) and it worked ok (with and without the preprocessor directives, and with and without ANOTHER_MACRO defined), but is it safe to do so?
I read the 16.3/9 paragraph from the answer of the first similar question, but is it true for my case too?
The C language leaves this as undefined behavior in 6.10.3 Macro replacement, ¶11:
If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.
So indeed it's wrong to do it.
GCC and perhaps other popular compiles don't catch it, which is probably why many users of the language are not aware. I encountered this when some of my code failed to compile on PCC (and promptly fixed the bug in my code).
Update: PJTraill asked in the comments for a case where it would be "misleading or meaningless" to have preprocessor directives inside a macro expansion. Here's an obvious one:
foo(a, b,
#ifdef BAR
c);
#else
d);
#endif
I'm not sure whether it would have been plausible for the language to specify that balanced preprocessor conditionals inside the macro expansion are okay, but I think you'd run into problems there too with ambiguities in the order in which they should be processed.
Do the following instead?
#ifdef ANOTHER_MACRO
FUNC_MACRO(aVal + offset, bVal);
#else
FUNC_MACRO(aVal, bVal);
#endif
EDIT: Addressing concern raised by comment; I do not know if the OP's method is specifically wrong (I think other answers cover that). However, succinctness and clarity are two aspects held to be pretty important when coding with C.
As such I would much prefer to find better ways to achieve what the OP seems to be trying, by slightly rethinking the situation such as I have offered above. I guess the OP may have used a triviallised example but I usually find with most C situations that if something is becoming overly complex or attempting to do something it does not seem like the language should allow, then there are better ways to achieve what is needed.
Is it possible with the C++ preprocessor to emit an #error if a particular #define is used? Something like this:
#define this_must_not_be_used #error You shouldn't use that.
In C++11,
#define this_must_not_be_used static_assert(false, "You shouldn't use that.");
In C11,
#define _Static_assert(0, "You shouldn't use that.");
For C before C11 or C++ before C++11, you'll have to think up some other invalid expression that contains a string that will show up in the error message. I'm thinking along the lines of
#define this_must_not_be_used ("You shouldn't use that",)
There is no standard way of defining a macro in such a way that its use, wherever it is, will give you a compilation error, especially not one that gives a clear and useful error message. For all you know, the code that uses it might just be stringizing its result, or it might be part of an assert condition that gets removed by the preprocessor.
For most practical purposes, putting something that cannot possibly be part of a valid C (or C++) program will be good enough.
Some implementations do have implementation-specific methods of achieving exactly what you ask for, though. For instance, with GCC, you can use
#pragma GCC poison this_should_not_be_used
where its subsequent use, no matter how it ends up used, will give:
error: attempt to use poisoned "this_should_not_be_used"
You may want to look at your own compiler's documentation to see if it has anything similar. You can also use conditional macro definitions, so that with GCC you use this approach, with your compiler you use your compiler's approach, and with an unknown compiler you fall back to the standard method of providing a macro definition that will probably lead to a difficult-to-read error message.
Do you mean something like follows:
#ifdef this_must_not_be_used
#error "You shouln't use that."
#endif
One in a while there's a need for a no-op statement in C++. For example when implementing assert() which is disabled in non-debug configuration (also see this question):
#ifdef _DEBUG
#define assert(x) if( !x ) { \
ThrowExcepion(__FILE__, __LINE__);\
} else {\
//noop here \
}
#else
#define assert(x) //noop here
#endif
So far I'm under impression that the right way is to use (void)0; for a no-op:
(void)0;
however I suspect that it might trigger warnings on some compilers - something like C4555: expression has no effect; expected expression with side-effect Visual C++ warning that is not emitted for this particular case but is emitted when there's no cast to void.
Is it universally portable? Is there a better way?
The simplest no-op is just having no code at all:
#define noop
Then user code will have:
if (condition) noop; else do_something();
The alternative that you mention is also a no-op: (void)0;, but if you are going to use that inside a macro, you should leave the ; aside for the caller to add:
#define noop (void)0
if (condition) noop; else do_something();
(If ; was part of the macro, then there would be an extra ; there)
I suspect that it might trigger warnings on some compilers
Unlikely, since ((void)0) is what the standard assert macro expands to when NDEBUG is defined. So any compiler that issues warnings for it will issue warnings whenever code that contains asserts is compiled for release. I expect that would be considered a bug by the users.
I suppose a compiler could avoid that problem by warning for your proposal (void)0 while treating only ((void)0) specially. So you might be better off using ((void)0), but I doubt it.
In general, casting something to void, with or without the extra enclosing parens, idiomatically means "ignore this". For example in C code that casts function parameters to void in order to suppress warnings for unused variables. So on that score too, a compiler that warned would be rather unpopular, since suppressing one warning would just give you another one.
Note that in C++, standard headers are permitted to include each other. Therefore, if you are using any standard header, assert might have been defined by that. So your code is non-portable on that account. If you're talking "universally portable", you normally should treat any macro defined in any standard header as a reserved identifier. You could undefine it, but using a different name for your own assertions would be more sensible. I know it's only an example, but I don't see why you'd ever want to define assert in a "universally portable" way, since all C++ implementations already have it, and it doesn't do what you're defining it to do here.
How about do { } while(0)? Yes it adds code, but I'm sure most compilers today are capable of optimizing it away.
; is considered as standard no-op. Note that it is possible that the compiler will not generate any code from it.
I think the objective here, and the reason not to define the macro to nothing, is to require the user to add a ;. For that purpose, anywhere a statement is legal, (void)0 (or ((void)0), or other variations thereupon) is fine.
I found this question because I needed to do the same thing at global scope, where a plain old statement is illegal. Fortunately, C++11 gives us an alternative: static_assert(true, "NO OP"). This can be used anywhere, and accomplishes my objective of requiring a ; after the macro. (In my case, the macro is a tag for a code generation tool that parses the source file, so when compiling the code as C++, it will always be a NO-OP.)
I'm rather late to the party on this one but I needed the same for a loop() in an Arduino project where all processing is done in timer interrupt service routines (ISR). Found the inline assembler code worked for me without defining a function:
void loop(){
__asm__("nop\n\t"); // Do nothing.
}
I recommend using:
static_cast<void> (0)
And what about:
#define NOP() ({(void)0;})
or just
#define NOP() ({;})
AFAIK, it is universally portable.
#define MYDEFINE()
will do as well.
Another option may be something like this:
void noop(...) {}
#define MYDEFINE() noop()
However, I'd stick to (void)0 or use intrinsics like __noop
inline void noop( ) {}
Self-documenting
this code will not omitted by optimization
static void nop_func() { }
typedef void (*nop_func_t)();
static nop_func_t nop = &nop_func;
for (...)
{
nop();
}
There are many ways, and here is the comparison I've made to some of them in MSVS2019 cpp compiler.
__asm {
nop
}
Transaltes to nop operation in disassembly which takes 1 machine cycle.
do {} while (0); generates some instructions which generates some more cycles.
Simple ; generates nothing.