[libvirt-users] [libvirt] ignore_value

Hi,using ignore_value in libvirt source code to do function return value processing,but I can’t understand about it,can you give me some tips?thanks very much!

On 04/27/2018 02:20 AM, gaosheng cui wrote:
Hi,using ignore_value in libvirt source code to do function return value processing,but I can’t understand about it,can you give me some tips?thanks very much!
Is your question about what ignore_value() does? It exists solely to shut up compiler warnings about anything declared with __attribute__((warn_unused_result)) (under our macro ATTRIBUTE_RETURN_CHECK), in cases where we are intentionally ignoring the return value (rather than assigning the value to a variable or using the function call in an 'if' conditional, the way the compiler warning would want us to do it). Many of the uses in libvirt code base are things like this in src/conf/domain_addr.c: char * virDomainPCIAddressAsString(virPCIDeviceAddressPtr addr) { char *str; ignore_value(virAsprintf(&str, "%.4x:%.2x:%.2x.%.1x", addr->domain, addr->bus, addr->slot, addr->function)); return str; } We intentionally marked virAsprintf() as requiring the compiler to warn if the return value is ignored, because in many cases, it really is a bug if virAsprintf() failed (memory allocation or otherwise) and returned NULL, but you didn't check it but blindly assumed that str is non-NULL. But for this particular callsite, virDomainPCIAddressAsString() is also documented as returning NULL on failure, so we can ignore the return value of virAsprintf() and still have correct semantics. You can think of 'ignore_value(foo());' the same as '(void*)foo();', except that the latter doesn't shut up all compilers. You only need to use ignore_value() in situations where the compiler warns you, and even then, only if you are sure that ignoring the value doesn't introduce bugs - so using it also serves as a visual indicator to reviewers that your choice to ignore the return value was intentional and should be checked for accuracy. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org

On 04/27/2018 11:15 AM, Eric Blake wrote:
You can think of 'ignore_value(foo());' the same as '(void*)foo();',
Typo, make that '(void)foo();'
except that the latter doesn't shut up all compilers.
-- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org

On 04/27/2018 11:15 AM, Eric Blake wrote:
On 04/27/2018 02:20 AM, gaosheng cui wrote:
Hi,using ignore_value in libvirt source code to do function return value processing,but I can’t understand about it,can you give me some tips?thanks very much!
Is your question about what ignore_value() does?
Or, if your question is "Where is ignore_value defined", the answer is that libvirt uses gnulib, and gnulib's "ignore-value.h" (imported during ./bootstrap if you are building from git; if you are building a release tarball then it was already part of the tarball under lib/) contains this definition: /* Normally casting an expression to void discards its value, but GCC versions 3.4 and newer have __attribute__ ((__warn_unused_result__)) which may cause unwanted diagnostics in that case. Use __typeof__ and __extension__ to work around the problem, if the workaround is known to be needed. */ #if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) # define ignore_value(x) \ (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; })) #else # define ignore_value(x) ((void) (x)) #endif -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
participants (2)
-
Eric Blake
-
gaosheng cui