Alternatives to printf() for MISRA C : 2004 compliant code

Viewed 932

I am new to coding using MISRA C guidelines.

The following are two rules in MISRA C 2004:

Rule 16.1 (required): Functions shall not be defined with a variable number of arguments. Rule 20.9 (required): The input/output library <stdio.h> shall not be used in production code.

This clearly means that I can't use printf in production code for it to be MISRA C compliant, because printf is a part of <stdio.h> and allows a variable number of arguments. So I set out on a quest to find out how I can write my own printf statement. So far I am unable to find any solution for this predicament. Any help from fellow developers would be appreciated.

4 Answers

so far I am unable to find any solution for this predicament

You have to use functions that print one (countable) things at a time. An example interface you might want to implement might look like the following:

print_string("Hello");
print_int(5);
print_char('\n');

so I set out on a quest to find out how I can write my own printf statement

Most MISRA-C systems are embedded systems where printf is just some bloated wrapper around an UART library. The usual solution is to develop your own logging/messaging tool instead. Not necessarily UART-based, might as well some other serial bus, or just 8 parallel data or some LCD/7-seg... all depending on what you need to display and if you intend for this to be part of the production code or not.

So how to do this is highly project-specific and it's typically more of a system design and electronics problem than a programming one.

EDIT

Since you seem to be making some sort of general-purpose library, one solution is to simply provide an API that returns strings to the caller, then let the caller worry about how to present them. That makes your lib MISRA-C compliant, while allowing the caller to print strings in whatever application-specific way they have available. For example:

void lib_getmsg (char* msg, size_t bufsize);

Where "lib" is some prefix for your library. Leave string allocation to the caller. Alternatively, the old-fashioned way:

lib_result_t  lib_dosomething (void);

// Returns LIB_OK if went OK, returns LIB_ERR in case of errors.
// To get more information, call lib_get_lastmsg.

const char* lib_get_lastmsg (void);

This returns a pointer to an internal static string allocated by your library. The downside of this is that it won't work well in multi-process environments.

You need to understand the rationale for the MISRA C guidelines, understand the context they are used in, and the circumstances of your own code.

You also need to understand that the MISRA Guidelines are not to be blindly followed with a tick-box mentality... you then need to appreciate that those nice folk at MISRA provide several chapters of useful material before the actual guidelines. Part of that is the Deviation procedure.

If you can justify why you feel you need to violate a guidelines, then use the deviation procedure that is specified. This requires you understand the nature of the violation, and what you are going to do to ensure the integrity of your application.

If you genuinely need to use printf() and you can justify that, use it with a deviation

On Linux, running on a modern x86_64 processor:

int main()
{
    char *s = "Hello, World!\n";
    long l = 14;
    long fd = 1;
    long syscall = 1;
    long ret = 0;
    __asm__("syscall"
            : "=a"(ret)
            : "a"(syscall),
              "D"(fd),
              "S"(s),
              "d"(l));
    return 0;
}

Output:

Hello, World!
Related