¿Es posible la garantía de seguridad de excepción sólida con un argumento de paso por valor que puede generar destrucción?

8

Suponga que tiene un tipo con un destructor de lanzamiento y una función que lo recibe por valor.
¿Puede esa operación proporcionar algo mejor que la garantía de excepción básica? O formulado de manera diferente, ¿se puede ignorar la destrucción del argumento que se pasó por valor al determinar si una operación tiene semántica de comisionamiento y retrotracción?

#include <cstdlib>

struct X {
    ~X() noexcept(0) {
        if(rand()%6 == 0) throw 0;
    }
    // some state
};

void update(database db, X arg) noexcept;

X x;
update(db, x);

Personalmente, basado en la definición de wikipedia

  
  1. Seguridad de excepción fuerte , también conocida como semántica de confirmación o retrotracción : las operaciones pueden fallar, pero se garantiza que las operaciones fallidas no tienen efectos secundarios, por lo que todos los datos conservan sus valores originales
  2.   

No creo que sea útil describir a update como altamente seguro de excepciones, aunque la función en sí misma ni siquiera puede lanzar.

Apreciaría que alguien me muestre la insensatez de mi comprensión actual o me dé un mejor argumento.

    
pregunta Deduplicator 24.11.2015 - 16:47

2 respuestas

7

Realmente no estoy seguro en retrospectiva, pero si update era genérico o si X era abstracto (por ejemplo: clonado y destruido), es decir, si update no podría saber nada concreto sobre X Luego, para todos los propósitos prácticos, lo describiría como una fuerte garantía de seguridad de excepción. Como mínimo, eso es lo más parecido a una garantía de seguridad excepcional que obtendrás en un contexto abstracto sin radiografías de un tipo de datos.

Sin embargo, X es concreto, lo que hace que esta pregunta sea mucho más confusa. Todavía estoy tentado de decir que update "tiene una fuerte garantía de seguridad de excepción" ya que está haciendo todo lo posible para hacerla cumplir. ¿Eso suena como una locura? A mí me parece, pero no puedo decirlo mucho mejor.

Especialmente en el contexto de un entorno de equipo donde un autor implementa update y el otro implementa X , nada podría proporcionar una garantía de seguridad excepcional, ya que X podría modificarse de manera tal que se rompa la garantía. Maneras completamente más allá del control de update . Por motivos prácticos, creo que update hace todo lo que puede y debe para revertir sus propios efectos secundarios en rutas excepcionales, prácticamente ofrece una gran garantía de seguridad de excepción.

De lo contrario, la fuerte garantía de seguridad de excepción se convierte en algo poco práctico para proporcionar en tantos escenarios. Las cosas podrían cambiar fuera del control de la función. Las cosas podrían ser abstractas en formas más allá del conocimiento de la función. Toda la garantía sería casi imposible de proporcionar en cualquier lugar. En ese caso, ¿podríamos decir que la fuerte garantía de excepción de update propaga una responsabilidad a X para cumplir, o es update lo que se necesita para saber cómo se implementará X en todo momento? No lo sé. Esto es muy poco práctico, y no me gustan las impracticaciones.

Así que voy a ir con el crudo, sí, " update es excepcionalmente seguro, pero X se fue a la ruina y arruinó todo. No es update's culpa al menos. No ¡demandar al autor de la actualización! Sue al autor de X ! ". Me gustaría describir a X simplemente como fubar aquí, y update como posiblemente brindando una fuerte garantía de seguridad de excepción que se está atornillando por el hecho de que X es fubar. Es decir, a menos que haya una comprensión muy difícil a nivel de interfaz que X's destructor está diseñado para lanzar, en cuyo caso no tengo idea de cómo describirlo, excepto como un "gran problema". Creo que necesitamos algunas letras pequeñas y exenciones de responsabilidad para cumplir con estas garantías. La actualización proporciona una garantía de seguridad de excepción sólida siempre que [...]. ¡No hay reembolsos si este no es el caso!

Esto es como una pregunta filosófica para mí, interesante para pensar pero tal vez una sin una respuesta perfecta. ¿Y qué son las garantías de todos modos? ¿Podemos garantizar algo? Podría garantizar que beber cerveza me emborracharía y eso podría parecer cierto todo el tiempo, pero ¿y si un extraterrestre interviene y usa algún tipo de tecnología alienígena que me hace estar sobrio, sin importar cuánto beba? No puedo garantizar que esto no suceda. Solo puedo decir que esto es altamente improbable y que si tal evento ocurriera, sería impotente en su contra. Yo hice mi parte. Bebi mi cerveza Se supone que debo emborracharme. Lo garantizo fuertemente. Pero no es cierto. Siempre hay alguna probabilidad, aunque sea astronómicamente remota, de que la garantía no sea cierta. ¿Qué hay de la seguridad del hilo? Bien, ¿qué sucede si la nave espacial extraterrestre viene y cambia nuestro hardware y reorganiza las instrucciones en la memoria de modo que una función formalmente segura para subprocesos ya no sea segura para subprocesos en tiempo de ejecución? No puedo garantizar que esto no suceda. Pero garantizaré la seguridad de los hilos sin tener en cuenta sin siquiera entrar en la letra pequeña de las naves espaciales extraterrestres, porque hace que las personas se sientan agradables y tranquilizadas, y lo que estoy diciendo es que estoy haciendo todo lo que está a mi alcance para lograrlo. garantía.

Descartes dijo una vez: "Creo que, por lo tanto, lo soy". ¿Cómo lo sabe? ¿Y si no lo es? Podría ser un "no soy", pero tal vez "no" puede "pensar". Ni siquiera sé si existo. ¿Qué significa pensar de todos modos? Es como una palabra que la gente usa para describir un proceso que parece ir introspectivamente y parece que nosotros, que tal vez ni siquiera existamos, estamos tomando decisiones.

¿Qué pasa si todos somos solo bits y bytes en alguna máquina? Como esa rubia o morena en la Matrix. Por cierto, ¿cómo puede una rubia o especialmente morena ser almacenada en un flujo de personajes tan pequeño? ¿Son como UTF2048? Era una especie de corriente alienígena de personajes, pero no parecía haber demasiados personajes únicos. Tal vez sea algún tipo de llamada de función. De todos modos, no estoy seguro de que podamos garantizar nada. Todo es relativo a lo que creemos que es verdad.

    
respondido por el user204677 12.12.2015 - 19:35
-1

Hablando técnicamente, quizás pueda proporcionar una fuerte garantía de excepción. Significativamente, solo puede proporcionar una fuerte garantía de excepción en el caso trivial donde no hace nada.

Herb Sutter habla de un caso similar (y más intuitivo) en el que una función toma un argumento por valor que tiene un constructor de copia de lanzamiento. Puede etiquetar tal función noexcept. Técnicamente, la excepción se produce en el "pegamento" entre el código de llamada y la función llamada, no dentro de la función en sí. Ese es el caso aquí también. Dado que la excepción no se lanza técnicamente dentro de la actualización, podría (quizás) argumentar que la actualización en sí misma no genera el error y, por lo tanto, puede ofrecer una garantía de excepción sólida.

Hablando en términos prácticos, si la actualización hace algo, entonces llamarlo (y no hacer nada más) puede hacer que el estado del mundo cambie y se genere una excepción, rompiendo la fuerte garantía de excepción.

    
respondido por el Nir Friedman 20.12.2015 - 17:14

Lea otras preguntas en las etiquetas