Mantosh Kumar
Mantosh Kumar

Reputation: 5741

How to get/implement "Uninitialized uses warning" message for built-in type member variable of a class?

#include<iostream>
struct a{   
   int x;
};

int foo() {
    a oa;
    return oa.x;
}

int bar() {
    int a;
    return a;
}

int main() {
    auto val = foo();
    std::cout<<val<<"\n";
    return 0;
}

If we compile and run the above sample.cpp we get the following result:

$g++ -Wall -std=c++11 sample.cpp -o sample
sample.cpp: In function ‘int bar()’:
sample.cpp:13:9: warning: ‘a’ is used uninitialized in this 
function [-Wuninitialized]
  return a;
         ^
$ ./sample 
-1643562384
$ ./sample 
991591024

For above program, compiler emits warning about uninitialized uses for variable a inside bar() function. However there is no warning emitted by compiler when foo() function tries to use the variable x of object oa of type struct a.

I am aware about the c++11 universal initialization feature and if we define struct a as below,then built-in int type default constructor would be called by default constructor of struct a.

struct a {
   int x{};
}

I wanted to know that with new features likes type traits/static_assert does it possible to implement such warning message under the above situation?.

Such things are possible in the languages like C# as everything is derived from the common class and hence default constructor takes care about this. Bjarne Stroustrup has mentioned in his "The C++ Programming Language" about this as The reason for this complication is to improve performance in rare critical cases.

struct Buf {
int count;
char buf[16∗1024];
};

We can use a Buf as a local variable without initializing it before using it as a target for an input operation. But I think if we can implement some mechanism to handle this, it would be great in many situations. This would be really useful as uninitialised variable uses contributes major source of non-deterministic bugs.

Upvotes: 3

Views: 219

Answers (1)

cdhowie
cdhowie

Reputation: 169018

This can only realistically work in very simple cases, as you show here. There are other cases where the compiler cannot even tell if the member variable was initialized before use. For example:

// a.h

void init_a(a & an_a);

// a.cpp

#include "a.h"

void init_a(a & an_a) {
    an_a.x = 1;
}

// b.cpp

#include "a.h"

int test() {
    a oa;
    init_a(oa);
    return oa.x;
}

Since init_a() is not defined in the same translation unit as test(), the compiler cannot know whether the x member is assigned by the time the return statement is reached.

So such a warning could only be triggered in cases where the compiler is able to prove that the member may not be initialized, and there are many situations where the compiler couldn't tell and would be unable to produce a warning. Therefore, having such a warning would only be able to catch extremely simple cases and would be of very limited usefulness.

Upvotes: 5

Related Questions