tutorial software para online espaƱol curso aprender c++ c++11 g++ object-lifetime

c++ - software - Advertencia falsa sobre el enlace temporal al miembro de referencia en el constructor



solidity software (2)

Como lo señaló Howard Hinnant y ya lo indicó el comentario de R Sahu, este es un error (que solía ser requerido por el estándar entonces roto; gracias a Tony D por señalarlo) en la forma en que GCC 4.8 trata las listas de inicializadores.

Cambiando el constructor en mi ejemplo original de

wrapper(const callback_func& cb) : w_cb {cb} { }

a

wrapper(const callback_func& cb) : w_cb (cb) { }

hace que la advertencia con GCC 4.8.3 desaparezca y el ejecutable creado Valgrind esté limpio. La diferencia de los dos archivos de ensamblaje es enorme, así que no la publico aquí. GCC 4.9.0 crea un código de ensamblaje idéntico para ambas versiones.

A continuación, reemplacé la std::function con una estructura definida por el usuario y eliminé copiar y mover constructores y operadores de asignación. De hecho, con GCC 4.8.3, esto retiene la advertencia pero ahora también da un error (un poco más útil) de que la línea de código anterior llama al constructor de copia eliminado de la estructura. Como se esperaba, no hay diferencia con GCC 4.9.0.

Entiendo que si un temporal está vinculado a un miembro de referencia en la lista de inicializadores del constructor, el objeto se destruirá a medida que el constructor regrese.

Sin embargo , considere el siguiente código:

#include <functional> #include <iostream> using callback_func = std::function<int(void)>; int func(const callback_func& callback) { struct wrapper { const callback_func& w_cb; wrapper(const callback_func& cb) : w_cb {cb} { } int call() { return this->w_cb() + this->w_cb(); } }; wrapper wrp {callback}; return wrp.call(); } int main() { std::cout << func([](){ return 21; }) << std::endl; return 0; }

Esto me parece perfectamente válido. El objeto de callback vivirá durante toda la ejecución de la func función y no se debe hacer una copia temporal para el constructor de la wrapper .

De hecho, GCC 4.9.0 compila bien con todas las advertencias habilitadas.

Sin embargo, el compilador GCC 4.8.2 me da la siguiente advertencia:

$ g++ -std=c++11 -W main.cpp main.cpp: In constructor ‘func(const callback_func&)::wrapper::wrapper(const callback_func&)’: main.cpp:12:48: warning: a temporary bound to ‘func(const callback_func&)::wrapper::w_cb’ only persists until the constructor exits [-Wextra] wrapper(const callback_func& cb) : w_cb {cb} { } ^

¿Es esto un falso positivo o estoy malinterpretando las vidas de los objetos?

Aquí están mis versiones exactas del compilador probado:

$ g++ --version g++ (GCC) 4.8.2 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ --version g++ (GCC) 4.9.0 20140604 (prerelease) Copyright (C) 2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.