RAII ( resource acquisition is initialization ) is a common language in C++; I recently had a small problem using it, which I summarize in this code (the code is not valid, it is for illustrative purposes only ):
template< typename T > class Algo {
bool enqueue( T arg ) {
struct raii {
T val;
~raii( ) {
// Hacemos algo con las variables ...
}
} RAII = { arg };
// Cuerpo real de la función ...
}
// Resto de la plantilla ...
};
Inside the function enqueue( )
we create a control structure; its only mission is to guarantee that a part of our code will be executed, even in the presence of exceptions . The C++ language guarantees that the destructor will be called . It is the equivalent in C++ to the blocks finally { ... }
present in other languages.
The problem I've run into is that the compiler, in an effort to keep us out of trouble, gives us an unused variable warning :
warning: unused RAII variable
In modern compilers , we can use the new features of C++11; specifically, the attributes ; more exactly, in C++17 we can use
} RAII [[maybe_unused]] = { arg };
In g++
, we can use __attribute((unused))__
or [[gnu::unused]]
(depending on the version). And it even sounds like something to me pragma _Unused
in other compilers.
Other, more manual methods consist of declaring and using a constructor; this way, the compiler sees that we 're using the instance, and doesn't give us its well-intentioned warning either.
The question:
Doesn't C++ provide a standard, agreed mechanism for using RAII? That is, to inform the compiler that the only use of an instance is to call its destructor.
Just do a conversion to
void
:The effect on the generated code is nil, since the compiler sees that you don't fetch the result and won't generate a single additional statement.
Another possibility... since in this case
T
it has to be a pointer (otherwise the destructor of the resource would be called automatically), is to replace that structure with aunique_ptr
:And you can even complete the matter a bit more if we add a destructor prepared for the occasion:
I present to you the technical document p0052r6 under study for its inclusion in C++20 (my translation).
About...
That has never been RAII's goal. The non-use of variables alarm appears for your RAII object circumstantially, not because it is RAII.
You can prevent that alarm from appearing by configuring the compiler to ignore that specific alarm, but I don't advise it. Another option would be to use compiler or language specific tools to mark the object as unused (option you are already familiar with). And if all that fails, you can do the conversion
(void)
as eferion suggests but to denote intentionality you should use a macro:I personally prefer to use a function, which has the same effect:
Being a template function, it will accept any type and being the received parameter anonymous, it will not complain about the lack of use of the parameter.