MISRA Discussion Forums
Rule 21.6 and snprintf() - Printable Version

+- MISRA Discussion Forums (https://forum.misra.org.uk)
+-- Forum: MISRA C (https://forum.misra.org.uk/forumdisplay.php?fid=4)
+--- Forum: General Questions (https://forum.misra.org.uk/forumdisplay.php?fid=27)
+--- Thread: Rule 21.6 and snprintf() (/showthread.php?tid=1412)



Rule 21.6 and snprintf() - dejanpan - 05-04-2018

We are using snprintf() function (https://linux.die.net/man/3/snprintf) in a framework that lets you program autonomous driving cars (our product).
The function is currently being used only for logging of console data on the secondary, non-real time computer.


However, both PCLint and Coverity static code analysis tools mark it as non-compliant:

Rule 21.6
The Standard Library input/output functions shall not be used
C90 [Unspecified 2–5, 16–18; Undefined 77–89; Implementation 53–68]
C99 [Unspecified 3–6, 34–37; Undefined 138–166, 186; Implementation J.3.12(14–32)] [Koenig 74]

Category: Required
Analysis: Decidable, Single Translation Unit
Applies to: C90, C99

Amplification
This rule applies to the functions that are specified as being provided by and, in C99,
their wide-character equivalents specified in Sections 7.24.2 and 7.24.3 of the C99 Standard as being
provided by .

None of these identifiers shall be used and no macro with one of these names shall be expanded.

Rationale
Streams and file I/O have unspecified, undefined and implementation-defined behaviours associated
with them.

See also
Rule 22.1, Rule 22.3, Rule 22.4, Rule 22.5, Rule 22. 6



We have a following rebuttal:
The problem is that if the source and destination string buffers in a snprintf() call are the same, the behavior is undefined.

These buffers are passed as char pointers to
Code:
snprintf()
. Checking that two pointer variables can never be the same in a program (in all possible executions) is called alias analysis. It is a static code analysis that static code analysis tools can do, but it usually is imprecise (can have false positives). So it is easier for them to ban the use of
Code:
snprintf()
altogether.

We claim that we can use snprintf() ONLY IF we ALWAYS check that the source and destination buffers are NOT the same before calling snprintf().

Code:
if source != destination:
  snprintf(...)
else:
  raise error

Pardon pseudo code but if I use actual C code it won't let me post this question.

Additionally, based on the rule's Rationale text it could be argued that the snprintf() call is OK since it's not a stream or file output call.

I would love to hear some thoughts from MISRA members.


Re: Rule 21.6 and snprintf() - dg1980 - 05-04-2018

There is no source buffer in the signature of snprintf.
You should carefully study Annex J.2 items 138-166 and 186 (as referenced in the rule) in ISO 9899 (C99 language specification) and you will realize that snprintf just does not belong in production level code.
At least i can't imagine any valid deviation permit.
Are you able to implement something like the trick below (_DEBUG not active for static analysis / release build)?

Code:
#ifdef _DEBUG
#define LOG_CONSOLE(str, size, format, ...) snprintf(str, size, format, __VA_ARGS)
#else
#define LOG_CONSOLE(str, size, format, ...) (void)0
#endif



Re: Rule 21.6 and snprintf() - misra-c - 24-04-2018

As mentioned by dg1980 there are a range of undefined behaviours associated with snprintf.
Using snprintf would require a deviation that addresses all those issues.


Re: Rule 21.6 and snprintf() - dejanpan - 01-05-2018

Dear misra-c and dg1980, thanks a lot for your feedback.

I miswrote "source buffer", I meant the format argument.

Further I would like to ask about "Annex J.2 items 138-166 and 186". Is the bullet point list from here: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf correctly enumerated in here https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior?

Or do you guys really count bullet points to determine which item is e.g. 138?


Re: Rule 21.6 and snprintf() - misra-c - 04-05-2018

Yes, we have enumerated the bullet point list from the original published version of the C99 Standard, which does not include subsequent Technical Corrigenda.

This is not the same as the draft version of C99 at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
nor the C11 list on the SEI CERT C page at
https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior