I'm using the IAR Embedded Workbench compiler and have an issue with precedence of #pragma with #if.
I'm using #if 0 during development to comment out code.
The #pragma in the code below is to suppress MISRA issues about using hex escape sequences in a C-String.
The code fragment:
#if 0
// Display the glyphs in the font.
// This is debug code.
#pragma diag_suppress=Pm118,Pm003
static const char * text[] =
{
// Limit rows to 20 characters.
" () -0123456789Vanot",
"y^?",
"\xE3\x81\x84" "\xE3\x81\x8A" "\xE3\x81\x8C",
};
#pragma diag_default=Pm118,Pm003
static const size_t quantity_text_lines =
sizeof (text) / sizeof(text[0]);
uint16_t y = 150U;
for (unsigned int i = 0u; i < quantity_text_lines; i)
{
cmd_text_convert(35U, y,
FONT_HEADING_HANDLE,
0u,
text[i]);
y = 60u;
}
#else
In the above code fragment, I'm getting errors:
Error[Pm118]: hexadecimal escape sequences shall not be used (MISRA C 2004 rule 4.1)
My understanding is that I should not be getting any warnings because the code is inside a #if 0 block.
FYI, when I change #if 0 to #if 1, there are no errors and no warnings generated.
Is the IAR compiler behaving correctly?
What's the ruling regarding the language standard(s) about this?
(The environment is actually C language, but can be compiled in C too.)
CodePudding user response:
The standard says that the #pragmas should be ignored, which is consistent with what you see. (The error message was not suppressed.)
6.10.1p6: … Each directive’s condition is checked in order. If it evaluates to false (zero), the group that it controls is skipped: directives are processed only through the name that determines the directive in order to keep track of the level of nested conditionals; the rest of the directives’ preprocessing tokens are ignored, as are the other preprocessing tokens in the group.
(So the only part of #pragma inside #if 0 that is examined is the token pragma, and it is only examined to see if it affects conditional nesting.)
The question is whether the compiler can raise a tokenisation error for a preprocessing token. I'd say that it shouldn't, but there is nothing in the standard which prevents a compiler from generating diagnostics whenever it feels like it. That's a Quality of Implementation (QOI) issue, which is subject to the whim of the consumer, not the standards committee.
In any event, MISRA is not part of the standard.
CodePudding user response:
Is the IAR compiler behaving correctly?
Pragmas or no pragmas, IAR is behaving surprisingly by performing MISRA conformance analysis on the contents of an #if 0 block at all, if indeed that's what it is doing. That seems inconsistent with C preprocessor semantics. Program text -- or more properly, preprocessing tokens -- following a conditional directive whose condition evaluates to zero is processed only enough to recognize the matching #else or #endif, and otherwise is ignored.
Possibly IAR's MISRA scanner is designed to ignore preprocessor conditionals, or to test both alternatives of each one. If it is indeed doing that then it is behaving surprisingly by not recognizing pragmas within those conditional blocks that it would recognize outside them.
I suspect that @rici has it right in supposing that the issue is flagged by IAR's source tokenizer, and then not suppressed on account the relevant #pragmas being ignored (as directed by the language specification). But this is within IAR's control. I would find it hard to accept an argument that IAR is free to implement MISRA compliance scanning, but not free to extend preprocessor behavior to properly support the associated pragma-based controls. Or for that matter, that it can't have preprocessor conditionals control MISRA conformance analysis directly where appropriate.
However,
What's the ruling regarding the language standard(s) about this?
The C language specification does not define any specific significance for the pragmas in question, and it does not define any procedure or semantics for MISRA compliance checking. It specifies that diagnostics must be issued for constraint violations, but does not limit the diagnostics that implementations may issue. This is why above I describe IAR's behavior as surprising rather than wrong. I might go so far as to call it buggy, but not on account of failure to conform to the language specification.
