c++g++gcc-warning

Yet another warning: ‘<anonymous>’ may be used uninitialized


I saw many other questions about the very same warning, but my code seems different.
And, over all, I get this only with -Os option.

#include <iostream>
using namespace std ;

template <class TYPE,class FUNC> struct AutoDestruct
    {
    const TYPE & var ;
    FUNC         func ;
    AutoDestruct ( const TYPE & v , FUNC f ) : var(v),func(f) {}
   ~AutoDestruct ()                          { func(var) ;}
    };

class Dictionary
    {
    public:
        Dictionary & wipe  () { cout << "Dictionary.wipe()\n" ; return *this ;}
    };

static void wipe_dict ( Dictionary * dict ) { dict->wipe() ;}
typedef AutoDestruct<Dictionary*,void(*)(Dictionary*)> AutoWipe ;
    
int main ()
    {
    cout << "enter main function    " << __DATE__ << "  " << __TIME__ << endl ;
    Dictionary headers ;
    AutoWipe   auto_wipe( &headers,wipe_dict ) ;
    cout << "exit main function\n" ;
    }

The command line is : g++ -std=c++11 -Os -Wall -Wextra test.cpp && ./a.out
N.B.: If I remove the -Os option, I get no warning.

The output is :

test.cpp: In function ‘int main()’:
test.cpp:9:48: warning: ‘<anonymous>’ may be used uninitialized [-Wmaybe-uninitialized]
    9 |    ~AutoDestruct ()                          { func(var) ;}
      |                                                ^~~~
test.cpp:25:46: note: ‘<anonymous>’ was declared here
   25 |     AutoWipe   auto_wipe( &headers,wipe_dict ) ;
      |                                              ^
enter main function    May 13 2024  20:14:01
exit main function
Dictionary.wipe()

and the compiler is : g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

This is a very simple extract of my real code, just to expose the warning.
But notice that in my real code, I get the warning AND a seg fault when executing the auto_wipe !

Any idea of the warning + seg fault cause ? Thanks in advance !


Solution

  • Thanks all ! At the end of the day, I solved my issue by just removing the const & from my template AutoDestruct.

    template <class TYPE,class FUNC> struct AutoDestruct
        {
        TYPE         var ;
        FUNC         func ;
        AutoDestruct ( TYPE v , FUNC f ) : var(v),func(f) {}
       ~AutoDestruct ()                          { func(var) ;}
        };
    

    So var stores a pointer and no more a reference.
    Thanks to the reverse order of the call of the destructors, I'm sure that wipe is called before the object is destructed.