Different ways of suppressing 'uninitialized variable warnings' in C

red0ct :

I have encountered multiple uses of the uninitialized_var() macro designed to get rid of warnings like:

warning: ‘ptr’ is used uninitialized in this function [-Wuninitialized]

For GCC (<linux/compiler-gcc.h>) it is defined such a way:

/*
 * A trick to suppress uninitialized variable warning without generating any
 * code
 */
#define uninitialized_var(x) x = x

But also I discovered that <linux/compiler-clang.h> has the same macro defined in a different way:

#define uninitialized_var(x) x = *(&(x))

Why we have two different definitions? For what reason the first way may be insufficient? Is the first way insufficient just for Clang or in some other cases too?


example:

#define uninitialized_var(x) x = x

struct some {
     int a;
     char b;
};

int main(void) {
     struct some *ptr;
     struct some *uninitialized_var(ptr2);

     if (1)
         printf("%d %d\n", ptr->a, ptr2->a); // warning about ptr, not ptr2
}
Eric Postpischil :

Compilers are made to recognize certain constructs as indications that the author intended something deliberately, when the compiler would otherwise warn about it. For example, given if (b = a), GCC and Clang both warn that an assignment is being used as a conditional, but they do not warn about if ((b = a)) even though it is equivalent in terms of the C standard. This particular construct with extra parentheses has simply been set as a way to tell the compiler the author truly intends this code.

Similarly, x = x has been set as a way to tell GCC not to warn about x being uninitialized. There are times where a function may appear to have a code path in which an object is used without being initialized, but the author knows the function is intended not to be used with parameters that would ever cause that particular code path to be executed and, for reasons of efficiency, they want to silence the compiler warning rather than add an initialization that is not actually necessary for program correctness.

Clang was presumably designed not to recognize GCC’s idiom for this and needed a different method.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=368581&siteId=1