Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different ways of suppressing 'uninitialized variable warnings' in C

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?


c 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
}
like image 396
red0ct Avatar asked Mar 06 '20 12:03

red0ct


People also ask

What are uninitialized variables in C?

An uninitialized variable is a variable that is declared but is not set to a definite known value before it is used. Use of uninitialized variables is similar to use of uninitialized memory and might be a source of errors of different kinds to occur during program execution.

How do you ignore a warning in make?

Try make -k instead of just make . That will 'continue' rather than stop. Show activity on this post. As an alternative to diving into the build system, try setting -Wno-error in CFLAGS, which you should be able to do through the environment (or at configure time, if using the GNU build system).

How does GCC treat warning errors?

You can use the -Werror compiler flag to turn all or some warnings into errors. Show activity on this post. You can use -fdiagnostics-show-option to see the -W option that applies to a particular warning. Unfortunately, in this case there isn't any specific option that covers that warning.

Which of the following option can be used to prevent all warning messages in GCC?

-Wno-coverage-invalid-line-number can be used to disable the warning or -Wno-error=coverage-invalid-line-number can be used to disable the error. Suppress warning messages emitted by #warning directives.


1 Answers

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.

like image 70
Eric Postpischil Avatar answered Oct 19 '22 22:10

Eric Postpischil