Ignoring return values in C

2019-01-17 14:23发布

Lately, I started using lint for static code analysis. One of the warning I get sometimes is regarding this issue. Let's say for instance that I've got the following function:

uint32_t foo( void );

And let's say that I delibertly ignore the return value of the function. To make the warning dissapear, one can write

(void) foo();

My question is, what is the "proper" way to write code like this, should I continue as I always did, since the compiler doesn't complain about it, or should I use the void for clarity, so other code maintainer will know that I delibertly ignored the return value.

When I look at the code like this ( with the void ), it looks pretty strange to me...

10条回答
欢心
2楼-- · 2019-01-17 14:47

One slightly more "beautiful" way of indicating unused results would be this:

/**
 * Wrapping your function call with ignore_result makes it more clear to
 * readers, compilers and linters that you are, in fact, ignoring the
 * function's return value on purpose.
 */
static inline void ignore_result(long long int unused_result) {
    (void) unused_result;
}

...

ignore_result(foo());

With C++, this may be extended to:

template<typename T>
inline void ignore_result(T /* unused result */) {}
查看更多
▲ chillily
3楼-- · 2019-01-17 14:53

Usually there are not too many functions the value of which you want to ignore. Splint, for example, allows to add a special comment that would let it know, that a return value of a specific function might be ignored. Unfortunately, this in effect disables all 'ignored returned value' warning related to that particular function.

Here is an example of Splint-clean program:

#include <stdio.h>

FILE /*@alt void@*/ *fopen(const char *path, const char *mode);

static int /*@alt void@*/ test(void)
{
   printf( "test called\n" );

   fopen( "test", "a" );

   return 0;
}

int main(void)
{  
   test();

   return 0;
}

The unpleasant part is that you need to add an additional prototype to a system function with a comment somewhere.

Btw,by default Splint doesn't complain about the return value of printf and of some other libc functions being unused. However, a stricter mode can be activated.

LINT allows something similar, but I have never used it. Here is what a documentation says.

LINT lets you mark functions with optional return values by using a directive similar to the #directives of the C preprocessor.

#pragma optresult

can be placed immediately before the definition of a function that returns an optional result. LINT then recognizes that this function returns a result that can be ignored; LINT does not give error messages if the result is ignored.

查看更多
做自己的国王
4楼-- · 2019-01-17 14:57

Other solution would be to actually use a value. Then you could remove the unused variable warning with a macro.

#define _unused(x) ((void)(x))

Then in your example, you'd have:

val = foo();
_unused(val); 
查看更多
兄弟一词,经得起流年.
5楼-- · 2019-01-17 14:58

For a static code checker to be useful, it should report also the ignored return values, which can lead very often to difficult to track errors - or missing error handling.

So you should keep the (void) or deactivate the check for printf. Now you have several options for doing it in a readable manner. I use to wrap the function inside a new function like for example

void printf_unchecked(const char* format, ...)

where the not so nice cast takes place. Perhaps it's more practical to do it using a preprocessor macro in this case because of the varargs...

查看更多
登录 后发表回答