Disable clang-tidy warning for a specific macro - c++

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.

Related

C/C++ no curly brace after if/for, how to lint it out?

Is there way to get rid or find by linting (or maybe seding/regexping) these nasty situations when your have just one line of code after if/for statement, without curly braces? Like this one:
if(condition)
return;
For reference why would I want to get rid of that - there are lots of reasons given in this thread:
What's the purpose of using braces (i.e. {}) for a single-line if or loop?
I maintain some legacy code, and deal with some not-really-finished code from other people, and from time to time stumble on situation when this code-style works like a trip wire when debugging:
if(condition_for_early_return)
LOG("Im here") // surprise surprise, I just broke control logic
return;
Also, I've seen code like that:
if(condition)
<tabs> do_smth();
<spaces> do_smth_else();
Of course if contains only first do_smth(), compiler is not confused. But because the do_ functions are visually aligned, I wonder - is this intended behaviour or is it a bug that was never found in this legacy code.
I know cppcheck does not catch these situation - already tried that.
Do you have any way of finding these traps automatically?
GCC has:
-Wmisleading-indentation (C and C++ only)
Warn when the indentation of the code does not reflect the block
structure. Specifically, a warning is issued for if, else, while, and
for clauses with a guarded statement that does not use braces,
followed by an unguarded statement with the same indentation.
In the following example, the call to “bar” is misleadingly indented
as if it were guarded by the “if” conditional.
if (some_condition ())
foo ();
bar (); /* Gotcha: this is not guarded by the "if". */
In the case of mixed tabs and spaces, the warning uses the -ftabstop=
option to determine if the statements line up (defaulting to 8).
The warning is not issued for code involving multiline preprocessor
logic such as the following example.
if (flagA)
foo (0);
#if SOME_CONDITION_THAT_DOES_NOT_HOLD
if (flagB)
#endif
foo (1);
The warning is not issued after a #line directive, since this
typically indicates autogenerated code, and no assumptions can be made
about the layout of the file that the directive references.
Note that this warning is enabled by -Wall in C and C++.
Alternatively, clang-format provides:
-InsertBraces (Boolean) clang-format 15
Insert braces after control statements (if, else, for, do, and while)
in C++ unless the control statements are inside macro definitions or
the braces would enclose preprocessor directives.
But also issues a warning:
Setting this option to true could lead to incorrect code formatting
due to clang-format’s lack of complete semantic information. As such,
extra care should be taken to review code changes made by this option.
A quick google showed that SonarSource's linter has a rule for this: https://rules.sonarsource.com/cpp/RSPEC-121
I believe there's a way to use this tool for free to some extent, so it should work.
Alternatively, clang-format supports the option to just add them since v15: https://clang.llvm.org/docs/ClangFormatStyleOptions.html#insertbraces
Clang-tidy actually has a check for that, and if I remember correctly, it can also fix things automatically for you (you should of course then manually go through all the changes and make sure they're correct)

What is visual studio equivalent of GCC attribute unused [duplicate]

I am trying to write a macro to use suppress unused variable warnings when the user wants them (e.g. in derived classes when you have not implemented the whole class yet). I know that I can remove the variable name... but to make it clear I would prefer a macro).
So far I have this:
#ifdef WIN32
#define UNUSED(x) x
#else
#define x __attribute__((unused))
#endif
Used like:
void test_fn(int UNUSED(test_var)) {...}
I saw this post: suppressing-is-never-used-and-is-never-assigned-to-warnings-in-c-sharp, but it gave me a result that I can't really use (multiline #pragmas).
So my question is, is there a MSVS equivalent of the __attribute__((unused))? - i.e. on the same line?
Note: this question does not answer how to do what I am asking: how-do-i-best-silence-a-warning-about-unused-variables since it does not cover how to use it within the function prototype in a way that works with both MSVS and gcc.
If a variable or function-argument is potentially unused, gcc's __attribute__((unused)) is designed to suppress any warning about it.
Now, if you want something portable, there are multiple choices:
If you don't use it,
and it's a function-argument, just don't name it.
otherwise, simply don't create it.
If it might be used under some circumstances, simply use it once definitely by casting to void:
(void)potentially_unused;
Yes, the second option is not in the prototype, but one has to make allowances.
Upgrade to C++17 and use [[maybe_unused]].
If your usage is only
void test_fn(int UNUSED(test_var)) {...}
I know that I can remove the variable name... but to make it clear I would prefer a macro).
So remove variable name through MACRO:
You can go with
#define UNUSED(x) /*Empty*/

How to disable inline assembly in GCC?

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.

Detecting an undeclared identifier before the compiler

I'm working on a multi-platform codebase, and on one of the platforms, sprintf_s isn't available, but snprintf does exist, so in this case the solution is to have the line
#define sprintf_s snprintf
However, I'd like to either automatically revert this (or throw a compile time error so I can do it manually) should the platform implement sprintf_s.
I've found multiple questions here to detect if a class has a member function defined (or an overload exists of a stream operator), but none for a function like sprintf_s.
(I'd rather not use anything experimental, but if std::experimental::is_detected is the only solution so be it).
The ideal solution looks something like
if !sprintf exists
#define sprintf_s snprintf
but something like the following would also be acceptable
static_assert(!sprintf_s_exists, "sprintf_s is now defined");
An implementation that provides sprintf_s() should define the macro __STDC_LIB_EXT1__ in <stdio.h>. You might also define __STDC_WANT_LIB_EXT1__ to 1 before including the header yourself.
You can also check for implementations you are sure support it, such as MSVC with a minimum version number, and enable it conditionally only for those.
The more general appriach is what auticonf traditionally did: attempt to compile a small program that calls the function you're testing for, and check the return value. If the program compiles and runs as expected, the script added a macro such as HAS_SPRINTF_S to the configuration file, and the program could then test for that.
Such problem (speaking generally) is not uncommon. Many systems solve it during configure phase of the build (when generating platform specific make or ninja files). There you would normally provide the build system generator with a small "feature test" app which would either compile fine or fail to compile, and you can base the logic of the build system (usually by having it define required compiler macros) based on either of outcomes.
In CMake something similar to the above is called cmake-compile-features

Universally compiler independent way of implementing an UNUSED macro in C/C++

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.