There are required pieces to formulate my problem.
Below are content of MyError.h
header file.
###########################
# myError.h
###########################
1 typedef enum
2 {
3 MySuccess = 0x00000000,
4 MyError1 = 0x00000001,
5 MyError2 = 0x00000003,
6 MyForce32 = 0x7FFFFFFF
7 } MyError;
8 #define PROPAGATE_ERROR_FAIL_MY_1(_err) \
9 do { \
10 e = (_err); \
11 if (e != MySuccess) \
12 { \
13 MY_UTILS_LOG_ERROR(e, __FILE__, __FUNCTION__, __LINE__, true, 0); \
14 goto fail; \
15 } \
16 } while (0)
17 #define MY_UTILS_LOG_ERROR(_err, _file, _func, _line, _propagating, _format, ...) \
18 do { \
19 MyUtilsLogError(MY_UTILS_ERROR_TAG, MY_UTILS_ERROR_PATH, \
20 (_err), (_file), (_func), (_line), \
21 (_propagating), (_format), ##__VA_ARGS__); \
22 } \
23 while (0)
24 void MyUtilsLogError(const char* tag, const char* path, MyError e, const char* file, const char* func,
uint32_t line, bool propagating, const char* format, ...)
//Here MyError is passed just to print the String for Error for example if we pass MyError1 then string MyError1 will be printed in logs on console.
Below are required pieces from MyError.c
file, which simply include above header file and calls the PROPAGATE_ERROR_FAIL_MY_1
macro in APIs.
#include "myerror.h"
static MyError foo(uint32_t x, uint32_t y) {
if (x==y) {
return MySuccess;
} else {
return MyError1;
}
}
static MyError fooCaller(void) {
MyError e = MySuccess;
uint32_t x = 1U, y = 1U;
PROPAGATE_ERROR_FAIL_MY_1(foo(x,y)); //This is where I get all kind of weird MISRA violation [1][2].
fail:
return e;
}
In myError.c
file I see below MISRA 2012 violations:
[1]: misra_c_2012_rule_10_4_violation: Essential type of the left hand operand "e" (enum) is not the same as that of the right operand "MySuccess"(boolean).
[2]: misra_c_2012_rule_11_9_violation: Literal "0" shall not be used as null pointer constant.
I'm not getting why MISRA is reporting 10.4 violation even though I'm comparing the same enum type at line#11 in myErro.h
file ?
Any clue why 10.9 violation is being reported here ? Is macro not good to use for MISRA ?
in
static MyError foo(uint32_t x, uint32_y) {
you want
static MyError foo(uint32_t x, uint32_t y) {
In
if (e != MYSuccess) \
you want
if (e != MySuccess) \
In
MY_UTILS_LOG_ERROR(e, __FILE__, __FUNCTION__, __LINE__, true, 0); \
there is not enough args, ISO C99 requires at least one argument for the "..." in a variadic macro
warning ISO C does not support __FUNCTION__
predefined identifier
Also MyUtilsLogError is not declared/defined of your question, what is its signature ? Does it knows at least what MyError is ?
I could solve issues with below approach:
Issue [1]: misra_c_2012_rule_10_4_violation: Essential type of the left hand operand "e" (enum) is not the same as that of the right operand "MySuccess"(boolean).
==>Fix: Rule 10.4 violation fix is:
8 #define PROPAGATE_ERROR_FAIL_MY_1(_err) \
9 do { \
10 e = (_err); \
11 + MyError errSuccess = MySuccess; /* This fixes the 10.4 violations */\
11 if (e != MySuccess) \
12 { \
13 MY_UTILS_LOG_ERROR(e, __FILE__, __FUNCTION__, __LINE__, true, 0); \
14 goto fail; \
15 } \
16 } while (0)
So holding the MySuccess
in separate MyError
var helps to fix the answer. But I don't know how this is fixing the issue here ? It seems without holding MySuccess
in separate var macro expansion simply places its value before comparison and MISRA catches this as violation.
Issue [2]: misra_c_2012_rule_11_9_violation: Literal "0" shall not be used as null pointer constant.
==>Fix: Rule 11.9 violation fix is:
- 13 MY_UTILS_LOG_ERROR(e, __FILE__, __FUNCTION__, __LINE__, true, 0); \
+ 13 MY_UTILS_LOG_ERROR(e, __FILE__, __FUNCTION__, __LINE__, true, ""); \
This fixes the issue because MyUtilsLogError() function expects format: arg as pointer to a const char (const char*). So we shouldn't pass 0
, passing ""
for format
arg fixes the Rule 11.9 violations.
User contributions licensed under CC BY-SA 3.0