I'm trying to utilize misra C:2012 checking in from cppcheck (v2.9). However, when executing on a particular file I get the following violations:
vehicle_controller.c:1494:2: style: All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #define’d before evaluation. [misra-c2012-20.9]
#if OS == LINUX_OS
^
src/emb/bwk/
I'm using the following command to execute:
$ cppcheck -DOS=LINUX_OS --addon=misra.json vehicle_controller.c
Is there a different way to pass #define to be properly picked up by the misra checking?
As per the examples within Rule 20.9, an undefined identifier results in a zero value:
#if OS == 0 /* Non-compliant - OS may be zero or undefined */
...
#endif
The MISRA compliant approach is to ensure that the identifier is defined before use. Thus:
#ifndef OS
... /* OS is undefined */
#else
#if OS == 0
... /* OS is defined as zero */
#else
... /* OS is defined as non-zero */
#endif
#endif
Related
I need to know is there a method for gcc to check presence of those awesome __builtin_MY_DESIRED_FUNCTIONs
For example, I'd like to use __builtin_nan and be sure it is available for my program and it won't fail during compilation time.
I'll be more specific: on clang there is __has_builtin "checker" so we can write smth like
#if __has_builtin(__builtin_nan)
But I can't find analog for gcc.
And probably I can rely just on gcc, like "Oh, I'm on gcc now, just let's assume all of those __builtin_ are here like in example below..."
#if __GNUC__
double mynan = __builtin_nan("0");
#endif
And probably it will work, till someone put this "-fno-builtin" compilation flag.
Good news! a __has_builtin was added in GCC 10 (see change notes):
The special operator __has_builtin (operand) may be used in constant
integer contexts and in preprocessor ‘#if’ and ‘#elif’ expressions to
test whether the symbol named by its operand is recognized as a
built-in function by GCC in the current language and conformance mode.
It evaluates to a constant integer with a nonzero value if the
argument refers to such a function, and to zero otherwise. The
operator may also be used in preprocessor ‘#if’ and ‘#elif’
expressions. The __has_builtin operator by itself, without any operand
or parentheses, acts as a predefined macro so that support for it can
be tested in portable code. Thus, the recommended use of the operator
is as follows:
#if defined __has_builtin
# if __has_builtin (__builtin_object_size)
# define builtin_object_size(ptr) __builtin_object_size (ptr, 2)
# endif
#endif
#ifndef builtin_object_size
# define builtin_object_size(ptr) ((size_t)-1)
#endif
No, you will have to use __GNUC__ and __GNUC_MINOR__ (and __GNUC_PATCHLEVEL__ if you use such gcc versions) to test for each release specific builtin function (gcc releases can be found here)
For example:
/* __builtin_mul_overflow_p added in gcc 7.4 */
#if (__GNUC__ > 7) || \
((__GNUC__ == 7) && (__GNUC_MINOR__ > 3))
#define BUILTIN_MUL_OVERFLOW_EXIST
#endif
#ifdef BUILTIN_MUL_OVERFLOW_EXIST
int c = __builtin_mul_overflow_p (3, 2, 3) ? 0 : 3 * 2;
#endif
And there is an open bug for exactly what you are asking about, in here.
If there is a code applicable on more than 1 project / variant than we use pre-processor switches (compiler switches) to enable or disable the code. For example if MACRO1, MACRO2 and MACRO3 are preprocessor directives or compiler switches in a project than
#if (defined MACRO1 || defined MACRO2)
/* Do something */
#elif (defined MACRO2 && defined MACRO3)
/* Do something */
#else
/* Do something */
#endif
This conditional #if statement yields MISRA warning 12.6 as
"boolean expression required for operator: '!'; the -strong(B,...) option can help provide Boolean-by-enforcement"
Can someone please tell me if there is an alternate way to write this conditional statement or how to justify it?
What does the following statement mean:
#define FAHAD
I am familiar with the statements like:
#define FAHAD 1
But what does the #define statement without a token signify?
Is it that it is similar to a constant definition?
Defining a constant without a value acts as a flag to the preprocessor, and can be used like so:
#define MY_FLAG
#ifdef MY_FLAG
/* If we defined MY_FLAG, we want this to be compiled */
#else
/* We did not define MY_FLAG, we want this to be compiled instead */
#endif
it means that FAHAD is defined, you can later check if it's defined or not with:
#ifdef FAHAD
//do something
#else
//something else
#endif
Or:
#ifndef FAHAD //if not defined
//do something
#endif
A real life example use is to check if a function or a header is available for your platform, usually a build system will define macros to indicate that some functions or headers exist before actually compiling, for example this checks if signal.h is available:
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif/*HAVE_SIGNAL_H*/
This checks if some function is available
#ifdef HAVE_SOME_FUNCTION
//use this function
#else
//else use another one
#endif
Any #define results in replacing the original identifier with the replacement tokens. If there are no replacement tokens, the replacement is empty:
#define DEF_A "some stuff"
#define DEF_B 42
#define DEF_C
printf("%s is %d\n", DEF_A, DEF_B DEF_C);
expands to:
printf("%s is %d\n", "some stuff", 42 );
I put a space between 42 and ) to indicate the "nothing" that DEF_C expanded-to, but in terms of the language at least, the output of the preprocessor is merely a stream of tokens. (Actual compilers generally let you see the preprocessor output. Whether there will be any white-space here depends on the actual preprocessor. For GNU cpp, there is one.)
As in the other answers so far, you can use #ifdef to test whether an identifier has been #defined. You can also write:
#if defined(DEF_C)
for instance. These tests are positive (i.e., the identifier is defined) even if the expansion is empty.
#define FAHAD
this will act like a compiler flag, under which some code can be done.
this will instruct the compiler to compile the code present under this compiler option
#ifdef FAHAD
printf();
#else
/* NA */
#endif
I regularly use object-like preprocessor macros as boolean flags in C code to turn on and off sections of code.
For example
#define DEBUG_PRINT 1
And then use it like
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
However, it comes a problem if the header file that contains the #define is forgotten to be included in the source code. Since the macro is not declared, the preprocessor treats it as if it equals 0, and the #if statement never runs.
When the header file is forgotten to be included, non-expected, unruly behaviour can occur.
Ideally, I would like to be able to both check that a macro is defined, and check that it equals a certain value, in one line. If it is not defined, the preprocessor throws an error (or warning).
I'm looking for something along the lines of:
#if-def-and-true-else-throw-error(DEBUG_PRINT)
...
#endif
It's like a combination of #ifdef and #if, and if it doesn't exist, uses #error.
I have explored a few avenues, however, preprocessor directives can't be used inside a #define block, and as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
This may not work for the general case (I don't think there's a general solution to what you're asking for), but for your specific example you might consider changing this sequence of code:
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
to:
if (DEBUG_PRINT == 1) {
printf("%s", "Testing");
}
It's no more verbose and will fail to compile if DEBUG_PRINT is not defined or if it's defined to be something that cannot be compared with 1.
as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
It can't be an error because the C standard specifies that behavior is legal. From section 6.10.1/3 of ISO C99 standard:
After all replacements due to macro expansion and the defined unary
operator have been performed, all remaining identifiers are replaced with the pp-number
0....
As Jim Balter notes in the comment below, though, some compilers (such as gcc) can issue warnings about it. However, since the behavior of substituting 0 for unrecognized preprocessor tokens is legal (and in many cases desirable), I'd expect that enabling such warnings in practice would generate a significant amount of noise.
There's no way to do exactly what you want. If you want to generate a compilation failure if the macro is not defined, you'll have to do it explicitly
#if !defined DEBUG_PRINT
#error DEBUG_PRINT is not defined.
#endif
for each source file that cares. Alternatively, you could convert your macro to a function-like macro and avoid using #if. For example, you could define a DEBUG_PRINT macro that expands to a printf call for debug builds but expands to nothing for non-debug builds. Any file that neglects to include the header defining the macro then would fail to compile.
Edit:
Regarding desirability, I have seen numerous times where code uses:
#if ENABLE_SOME_CODE
...
#endif
instead of:
#ifdef ENABLE_SOME_CODE
...
#endif
so that #define ENABLE_SOME_CODE 0 disables the code rather than enables it.
Rather than using DEBUG_PRINT directly in your source files, put this in the header file:
#if !defined(DEBUG_PRINT)
#error DEBUG_PRINT is not defined
#endif
#if DEBUG_PRINT
#define PrintDebug([args]) [definition]
#else
#define PrintDebug
#endif
Any source file that uses PrintDebug but doesn't include the header file will fail to compile.
If you need other code than calls to PrintDebug to be compiled based on DEBUG_PRINT, consider using Michael Burr's suggestion of using plain if rather than #if (yes, the optimizer will not generate code within a false constant test).
Edit:
And you can generalize PrintDebug above to include or exclude arbitrary code as long as you don't have commas that look like macro arguments:
#if !defined(IF_DEBUG)
#error IF_DEBUG is not defined
#endif
#if IF_DEBUG
#define IfDebug(code) code
#else
#define IfDebug(code)
#endif
Then you can write stuff like
IfDebug(int count1;) // IfDebug(int count1, count2;) won't work
IfDebug(int count2;)
...
IfDebug(count1++; count2++;)
Yes you can check both:
#if defined DEBUG && DEBUG == 1
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
In this example even when #define DEBUG 0 but it is not equal to 1 thus nothing will be printed.
You can do even this:
#if defined DEBUG && DEBUG
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
Here if you #define DEBUG 0 and then D(1,2,3) also nothing will be printed
DOC
Simply create a macro DEBUG_PRINT that does the actual printing:
#define DEBUG_PRINT(n, str) \
\
if(n == 1) \
{ \
printf("%s", str); \
} \
else if(n == 2) \
{ \
do_something_else(); \
} \
\
#endif
#include <stdio.h>
int main()
{
DEBUG_PRINT(1, "testing");
}
If the macro isn't defined, then you will get a compiler error because the symbol is not recognized.
#if 0 // 0/1
#define DEBUG_PRINT printf("%s", "Testing")
#else
#define DEBUG_PRINT printf("%s")
#endif
So when "if 0" it'll do nothing and when "if 1" it'll execute the defined macro.
I had envisaged one of these in the project preferences
TESTING = HOST
TESTING = TARGET
TESTING not defined at all
My problem is with the latter.
It seems that instead of
#if TESTING==HOST
#error "HOST defined" // add temporarilly for testing porpoises
#endif
I need to code
#ifdef TESTING
#if TESTING==HOST
#error "HOST defined" // add temporarilly for testing porpoises
#endif
#endif
I am convinced that this is not-standard behaviour, since if TESTING is not defined then it certainly doesn't equal HOST, and I do not need that extra #ifdef TESTING with the GCC compiler.
However, when I use the Atmel AVR Studio (which I think is based on MS Visual Studio), it is necessary to add that initial #ifdef TESTING in a few dozen places :-(
It looks like I have no choice, but I just wondered if any C standard acually requires this.
#if TESTING==HOST
If TESTING is not defined, then
it is equivalent to:
#if 0==HOST
From the C Standard:
(C99, 6.10.1p4) "After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0""
And note that you can do this:
#ifndef TESTING
...
#elif TESTING == HOST
...
#elif TESTING == TARGET
...
#else
#error "Unexpected value of TESTING."
#endif
Also:
#if defined(TESTING) && TESTING == HOST
...
#endif
If you want to collapse the tests. The parenthesis are optional (#if defined TESTING is valid) but I think it's clearer to include them, especially when you start adding additional logic.
The original C preprocessors required explicit #ifdef validation before using a symbol. It is a relatively recent innovation (perhaps driven by scripting languages like Javascript) to assume that undefined symbols have a default value.
Why don't you always insure the symbol is defined?:
#ifndef TESTING
#define TESTING (default value)
#endif
#if TESTING==HOST
...
#elif TESTING==TARGET
...
#else
...
#endif
Alternative, maybe force a selection?:
#ifndef TESTING
#error You must define a value for TESTING
#endif
I had the same problem. It used to be the compiler would error if the #if parameter was not defined which is what I wanted. I learned the hard way this is no longer the case. The solution I came up with is as follows:
#define BUILDOPT 3
#if 3/BUILDOPT == 1
<compile>
#endif
If BUILDOPT is not defined you get a compile error for divide by 0. If BUILDOPT != 3 && > 0 the #if fails.
My final implementation is to set BUILDOPT to 1 to enable the code, > 1 to disable. Then the #if becomes #if 1/BUILDOPT==1.