El comportamiento indefinido mató a mi gato [cerrado]


82

El comportamiento indefinido mató a mi gato

Es bien sabido que un comportamiento indefinido puede matar a su gato [cita requerida] .
Pero puede?

Tu tarea

  1. Escriba un programa que invoque un comportamiento indefinido.
  2. Describa un escenario que comience con la ejecución del programa anterior, que resulte en un felis catus que termine su vida mientras sea de su propiedad, como resultado de la mencionada UB.
  3. Estime la probabilidad para cada etapa en el escenario.
  4. Calcule la probabilidad total de que una sola ejecución del programa mate a su gato.

Reglas

  1. Este es un , así que sé creativo si puedes.
  2. Este es un desafío relacionado con la programación, por lo que la cadena de eventos debe estar principalmente dentro de la computadora, no en el mundo real (por supuesto, si tiene que llegar al mundo real si es donde está su gato).
  3. Si elige un idioma que no tiene un comportamiento indefinido, use algo similar.
  4. Ningún animal puede ser dañado en la producción de su respuesta.

Puntuación

Recuento de votos más la probabilidad total del escenario (que no puede exceder 1).

Ejemplo en C:

main(){printf();}

Guión:

  1. printfllamado con basura de la pila - comportamiento indefinido. Probabilidad: 100%.
  2. El primer parámetro pasa a ser la cadena Your cat is ugly!. Probabilidad: (1/256) 17 = (1.148 * 10 -37 )%.
  3. Al ver el mensaje, tomas tu arma y le disparas a tu gato. Probabilidad: 3%.
  4. El gato muere. Probabilidad: 93%.

Probabilidad total: (3.202 * 10 -39 )%.


50
1) Invocar un comportamiento indefinido 2) Mantenerse inspirado por el simple hecho de que podría invocar un comportamiento indefinido y vivir una vida larga y feliz 3) El gato muere de vejez. Probabilidad total: 100%
Geobits

55
@Oberon me mataría si no pudiera encontrar una sola forma de crear una UB después de programar durante tanto tiempo. Entonces el gato ya no estaría en mi poder. Invocar a la UB me mantiene con vida, de modo que "... terminando su vida mientras es de su propiedad , como resultado ...". Análisis ambiguo FTW.
Geobits

8
Me divertiría más si alguien reinterpreta esto para matar el catcomando o algo por el estilo.
keshlam

55
-1 Me encantan los gatos. ¿Por qué gatos? ¿Por qué no matar alimañas?
VX

22
Si se va a comer un gato, Python es una solución.
Nicolas Barbulesco

Respuestas:


113

C

La mayoría de las respuestas a esta pregunta malinterpretaron la pregunta en el sentido de que estaba matando el catproceso en un sistema UNIX. Aquí hay un programa que puede causar la desaparición de una forma de vida biológica de la especie Felis Cattus como se especifica en la pregunta.

Este ejemplo se ejecuta en Windows, pero se puede portar fácilmente a la mayoría de los sistemas operativos UNIX al reemplazarlo iexplore -kcon el comando para iniciar un navegador web instalado.

#include <stdlib.h>
#include <stdio.h>    

int main() {
    char i; // uninitialised
    printf("Redirecting you to a website which will inform you how to properly feed your cat.");
    if (i != 42) {
         system("iexplore -k https://pets.stackexchange.com/questions/tagged/cats+diet");
    } else {
         system("iexplore -k https://cooking.stackexchange.com/questions/tagged/chocolate");
    }
    return 0;
}

Este programa pretende proporcionar consejos sobre la dieta del gato al usuario.

Iniciará Internet Explorer y dirigirá al usuario a la lista de intercambio de mascotas que incluye muchas preguntas útiles sobre cómo alimentar a los gatos. Sin embargo, existe una baja probabilidad (1/256) de que envíe al usuario a cocinar stackchange en lugar de enumerar consejos sobre cómo preparar platos que contienen chocolate, que es altamente tóxico para los gatos . Para empeorar las cosas, lanzará Internet Explorer en modo quiosco (pantalla completa), que oculta la barra de direcciones y es difícil de escapar para un usuario no experto en tecnología.

Esta artimaña inteligente convencerá al usuario de que alimente a su gato con chocolate creyendo que es una dieta adecuada para él, lo que hará que lo mate inadvertidamente.


3
¡La pluma es mas poderosa que la espada! :)
Pieter Witvoet

12
Esta parece ser la única solución hasta el momento que tiene alguna posibilidad realista de matar a un gato. Me veo obligado a votar, aunque sinceramente espero que nadie lo ponga en práctica.
Charles Staats

43
Internet Explorer podría matar a tu gato por sí solo.
Michael Hampton

44
¿Puedes agregar el escenario, paso a paso, que mata al gato, con el análisis de probabilidad (como en el ejemplo)? Tal como están las cosas, esta no es una respuesta válida.
Ugoren

3
El uso de Internet Explorer induce un comportamiento indefinido en ME. - Lo siento, tenía que decir eso.
tomsmeding

88

Golpetazo

De acuerdo con esto , INT_MIN % -1puede o no estar indefinido (¿qué ???) , por lo que puede causar problemas para cualquier lenguaje implementado en c / c ++.

#!/bin/bash

cat <<< $((2**63%-1))

Se catmatará temprano si el bashproceso padre falla, lo que puede suceder o no.

En mi VM obtengo esta salida:

$ ./schroedinger.sh
./schroedinger.sh: line 3:  7805 Floating point exception(core dumped) cat <<< $((2**63/-1))
$ 

(Realmente no entiendo el puntaje de esta pregunta, pero aquí va de todos modos)

Calcular $((2**63%-1)). El bloqueo siempre ocurre en bash 4.2.25, pero parece que se cuelga en algunas versiones 3.x. Más incertidumbre Podría decirle la probabilidad exacta, pero debido al principio de incertidumbre de Heisenburg, caería en un agujero negro. O algo. Así que creo que podemos decir con seguridad que la probabilidad es aproximadamente del 42%.


44
@ klingt.net: Se llama "Here Strings" - es mucho más fácil de buscar ... es un atajo paraecho $((-2**63/-1)) | cat
VX

14
+1 por usar real cat.
Alvin Wong

1
@mardavi INT_MAX = 2^63 - 1. Si agregamos 1 a INT_MAX, el espacio numérico de 64 bits se envuelve y obtenemos INT_MIN. En otras palabras firmado aritmética entera de 64 bits, 2^63 == -2^63. Podría haber utilizado -2**63, pero prefería la brevedad sin el -, ya que la aritmética modular es la misma en este caso.
Digital Trauma


1
¿Puedes agregar el escenario, paso a paso, que mata al gato, con el análisis de probabilidad (como en el ejemplo)? Tal como están las cosas, esta no es una respuesta válida.
Ugoren

40

C (punto de secuencia)

deadcat.c:

#include <stdio.h>
int main()
{
    int i=3;
    int k=0;
    k=i+(++i);
    if (k==7)
        printf("The cat is fine. k=i+(++i) =%d\n",k);
    else
        printf("Urgent Notice: Your cat has rabies. k=i+(++i) =%d\n",k);
}

Ejecución (o no):

$ clang -w deadcat.c -o deadcat; ./deadcat
The cat is fine. k=i+(++i) =7
$ gcc deadcat.c -o deadcat; ./deadcat
Urgent Notice: Your cat has rabies. k=i+(++i) =8

Escenario y probabilidad

Suponiendo que el cinco por ciento de las personas que ejecutan este programa usan clang para compilar código C (frente al 90 por ciento que usa gcc y el 5 por ciento que usa otros compiladores de C):

Probabilidad de obtener "El gato está bien". = .050
 Probabilidad de recibir "Aviso urgente: su gato tiene rabia". = .950

 Probabilidad de reaccionar a "Tu gato tiene rabia" poniéndolo abajo = .040
 Probabilidad de ignorar el aviso = .900
 Probabilidad de llevar al gato al veterinario para el tratamiento = .060

 Probabilidad total de vida del gato: .05 + .95 * (.90 + .06) = .962
 Probabilidad total de muerte del gato: .95 * .04 = .038
 Comprobación: probabilidad total de que el gato viva o muera: = 1.000

Explicación:

k = i + (++ i) accede y cambia "i" entre puntos de secuencia. La probabilidad no es determinable por el programa; depende de la elección del compilador, que realiza el usuario. "Indefinido" no significa necesariamente "aleatorio".

Ver https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points


44
+1 por demostrar el comportamiento con diferentes compiladores.
ntoskrnl

1
nivel de optimización también puede cambiar el comportamiento
monstruo de trinquete

1
@ratchet freak: Sí, pero no pude demostrarlo con este problema en particular. Intenté -O0, -O1, -O2 y -O3 en varias versiones de gcc que van desde gcc-4.2.3 a gcc-4.8.2 y cc-5.0 en SunOS, pero todos mataron al gato.
Glenn Randers-Pehrson

2
¿Puedes agregar el escenario, paso a paso, que mata al gato, con el análisis de probabilidad (como en el ejemplo)? Tal como están las cosas, esta no es una respuesta válida.
Ugoren

1
Supuse que todos los gatos que fueron llevados al veterinario para recibir tratamiento vivirían. Probablemente algunos de ellos morirán por contraer una enfermedad felina transmisible o por negligencia veterinaria. Eso podría cambiar un poco las probabilidades finales, por decir .96 / .04
Glenn Randers-Pehrson

37

C

Trasfondo

Mi esposa heredó un gato de la familia. Desafortunadamente, soy muy alérgico a los animales. El gato ya había pasado su mejor momento y debería haber sido sacrificado incluso antes de que lo obtuviéramos, pero no pudo deshacerse de él debido a su valor sentimental. Elaboré un plan para poner fin a mi sufrimiento.

Nos íbamos de vacaciones, pero ella no quería subir al gato en la oficina del veterinario. Le preocupaba que contrajera enfermedades o fuera maltratada. Creé un alimentador automático de gatos para que pudiéramos dejarlo en casa. Escribí el firmware del microcontrolador en C. El archivo que contenía se mainparecía al código siguiente.

Sin embargo, mi esposa también es programadora y conocía mis sentimientos hacia el gato, por lo que insistió en una revisión del código antes de aceptar dejarlo en casa sin supervisión. Ella tenía varias preocupaciones, incluyendo:

  • main no tiene una firma que cumpla con los estándares (para una implementación alojada)
  • main no devuelve un valor
  • tempTmse usa sin inicializar ya que mallocse llamó en lugar decalloc
  • el valor de retorno de mallocno se debe emitir
  • El tiempo del microcontrolador puede ser impreciso o no se puede transferir (similar a los problemas de Y2K o Unix time 2038)
  • la elapsedTimevariable puede no tener suficiente rango

Le tomó mucho tiempo convencer, pero finalmente estuvo de acuerdo en que las tesis no eran problemas por varias razones (no estaba de más que ya llegáramos tarde a nuestro vuelo). Como no había tiempo para las pruebas en vivo, ella aprobó el código y nos fuimos de vacaciones. Cuando regresamos unas semanas más tarde, mi miseria del gato había terminado (aunque como resultado ahora tengo mucho más).

† Escenario completamente ficticio, no se preocupe.


Código

#include <time.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

//#include "feedcat.h"
// contains extern void FeedCat(struct tm *);
// implemented in feedcat.c
// stub included here for demonstration only
#include <stdio.h>
// passed by pointer to avoid putting large structure on stack (which is very limited)
void FeedCat(struct tm *amPm)
{
    if(amPm->tm_hour >= 12)
        printf("Feeding cat dinner portion\n");
    else
        printf("Feeding cat breakfast portion\n");
}

// fallback value calculated based on MCU clock rate and average CPI
const uintmax_t FALLBACK_COUNTER_LIMIT = UINTMAX_MAX;

int main (void (*irqVector)(void))
{
    // small stack variables
    // seconds since last feed
    int elapsedTime = 0;
    // fallback fail-safe counter
    uintmax_t loopIterationsSinceFeed = 0;
    // last time cat was fed
    time_t lastFeedingTime;
    // current time
    time_t nowTime;

    // large struct on the heap
    // stores converted calendar time to help determine how much food to
    // dispense (morning vs. evening)
    struct tm * tempTm = (struct tm *)malloc(sizeof(struct tm));

    // assume the cat hasn't been fed for a long time (in case, for instance,
    // the feeder lost power), so make sure it's fed the first time through
    lastFeedingTime = (size_t)(-1);

    while(1)
    {
        // increment fallback counter to protect in case of time loss
        // or other anomaly
        loopIterationsSinceFeed++;

        // get current time, write into to nowTime 
        time(&nowTime);

        // calculate time since last feeding
        elapsedTime = (int)difftime(nowTime, lastFeedingTime);

        // get calendar time, write into tempTm since localtime uses an
        // internal static variable
        memcpy(&tempTm, localtime(&nowTime), sizeof(struct tm));

        // feed the cat if 12 hours have elapsed or if our fallback
        // counter reaches the limit
        if(  elapsedTime >= 12*60*60 || 
             loopIterationsSinceFeed >= FALLBACK_COUNTER_LIMIT)
        {
            // dispense food
            FeedCat(tempTm);

            // update last feeding time
            time(&lastFeedingTime);

            // reset fallback counter
            loopIterationsSinceFeed = 0;
        }
    }
}

Comportamiento indefinido:

Para aquellos que no quieren molestarse en encontrar la UB ellos mismos:

Definitivamente hay un comportamiento local específico, no especificado y definido por la implementación en este código, pero todo debería funcionar correctamente. El problema está en las siguientes líneas de código:

struct tm * tempTm //... //... memcpy(&tempTm, localtime(&nowTime), sizeof(struct tm));
memcpysobrescribe el tempTMpuntero en lugar del objeto al que apunta, rompiendo la pila. Esto sobrescribe, además de otras cosas, elapsedTimey loopIterationsSinceFeed. Aquí hay un ejemplo de ejecución donde imprimí los valores:

pre-smash : elapsedTime=1394210441 loopIterationsSinceFeed=1 post-smash : elapsedTime=65 loopIterationsSinceFeed=0


Probabilidad de matar al gato:

  • Dado el entorno de ejecución restringido y la cadena de compilación, siempre se produce el comportamiento indefinido.
  • Del mismo modo, el comportamiento indefinido siempre evita que el comedero para gatos funcione como se esperaba (o más bien, le permite "trabajar" como se pretende).
  • Si el alimentador no funciona, es extremadamente probable que el gato muera. Este no es un gato que pueda valerse por sí mismo, y no pude pedirle al vecino que lo mirara.

Estimo que el gato muere con probabilidad 0.995 .


Es el (primero) &en la memoria, ¿verdad?
Score_Under

@Score_Under Sí, déjame editar un poco la respuesta. Jugué con otras formas de aprovechar el comportamiento indefinido, pero la mayoría eran aún más obvias.
Jerry

1
+1 por matar a un gato, no cat.
Kevin

31

golpetazo

Versión clásica

cat & # This is your cat.
pkill -$RANDOM cat

Tiene la ventaja de matar a todos los gatos en su rango.

Tenga en cuenta que el proceso se detiene de inmediato, por lo que la única forma de finalizarlo con una sola invocación de pkill es enviar SIGKILL (9).

Por lo tanto:

p(SUCCESS) = p(RANDOM == 9) = 0.0275 %


Versión cuántica

schroedinger=/dev/null             # We'll need this guy.
heisenberg=/dev/urandom            # Also needed, for uncertainty principle.
cat $heisenberg > $schroedinger &  # Steal cat from Heisenberg and give it to Schrödinger.
felix=$!                           # Name cat for future references.
exec 2> $schroedinger              # Send all results to Schrödinger.
kill -SIGSTOP $felix               # Catch Felix and put him into a box.
if (($RANDOM & 1))                 # Flip a coin.
then kill $felix                   # Heads: Kill! Kill! Kill!
fi                                 # By now, Felix can be thought of as both alive and dead.
read -sn 1                         # Wait for somebody to open the box.
kill -SIGCONT $felix               # Let him open it.
if ps p $felix > $schroedinger     # Let Schrödinger check on Felix.
then echo The cat is alive.        # Hooray for tails!
else echo The cat is dead.         # At least, now we know.
fi                                 # This concludes the experiment.
kill -SIGKILL $felix               # Felix is no longer required.

Probabilidad de matar al gato durante el experimento: 50%


+1 Pero creo que es bastante más probable que eso. SIGINT (2), SIGQUIT (3), SIGABRT (6), SIGPIPE (13) y SIGTERM (15), al menos, lo mata aquí.
l0b0

@ l0b0: No lo hace, al menos no de inmediato. cat &intenta leer desde la terminal, pero no puede. Cualquiera de las señales que mencionó (y algunas más) funcionará si envía SIGCONT (18) después. Además, estoy de acuerdo en que colgar y terminar con el gato sería lo mismo que matarlo , pero interrumpirlo no parece satisfactorio ...: P
Dennis

3
El comportamiento indefinido está utilizando una característica de un lenguaje que se ha especificado como indefinido . Es decir, los diseñadores de lenguaje han dejado a propósito el comportamiento de una construcción sintáctica indefinido para facilitar la implementación o para indicar que la construcción nunca debe usarse en ningún programa válido. El comportamiento indefinido generalmente no tiene nada que ver con la generación de números aleatorios, y aquí no se utiliza ningún comportamiento indefinido.
OregonTrail

@OregonTrail: Las reglas dicen que si elige un idioma que no tiene un comportamiento indefinido, use algo similar. Bash no tiene un comportamiento indefinido, por lo que utilicé números aleatorios.
Dennis

3
Hay un montón de comportamientos indefinidos en el entorno de bash que se pueden usar. Por ejemplo, la respuesta de @DigitalTrauma Bash's printf también usa printf del sistema, que tiene un comportamiento indefinido.
OregonTrail

17

C

Tenga en cuenta que esto solo funciona en Linux.

main() {
  FILE *f = fopen("skynet", "w");
  srand(time(0));
  while(rand() != rand())
    fputc(rand()%256, f);
  fclose(f);
  system("chmod +x skynet");
  system("./skynet");
}
  1. Escribir datos aleatorios en un archivo e invocarlo (100%)
  2. Los datos aleatorios son el código fuente de skynet (1x10 ^ -999999999999999999999999999999999999999999999999999999999999999, aprox.)
  3. Gato muere en el día del juicio final resultante (99.999%)

Probabilidad total: 1x10 ^ -999999999999999999999999999999999999999999999999999999999999999, aprox.


hmmmm, que es skynet?
Sarge Borsch

20
¿Dónde está el comportamiento indefinido?
ugoren


1
@ugoren Creo que ejecutar un archivo con contenido aleatorio no está realmente definido.
11684

2
@ 11684, si el contenido es el código de skynet, los programadores de skynet saben lo que están haciendo, no hay un comportamiento indefinido.
Ugoren

15

C ++

Tu gato está muerto y vivo hasta que tengas curiosidad. Entonces te das cuenta de que hay una probabilidad de 0.5 de que tu gato esté muerto.

#ifdef WIN32
#pragma warning(disable: 4700)
#endif
#include <random>
#include <iostream>
#include <vector>
#include <climits>
#include <memory>
class Cat
{
public:
    enum class State {DEAD, ALIVE};
    Cat()
    {
        int x; // Uninitialized Variable on Stack
        if (x % 2 == 0) // Is the Uninitialized Variable even? 50-50
        {
            m_dead = State::DEAD;

        }
        else
        {
            m_dead = State::ALIVE;
        }
    };
    operator State() //Check if your Cat is Dead / Alive
    {
        if (m_dead == State::DEAD)
        {
            delete this; //Boom Cat is dead
            std::cout<<"Your Curiosity killed your Cat"<<std::endl;
            return false;
        }
        return m_dead;
    }
private:
    State m_dead;
};

class Schrödinger
{
public:
    Schrödinger(size_t size):m_size(size)
    {
        for(size_t i = 0; i < size; i++)
        {
            cats.push_back(new Cat());
        }
    }
    ~Schrödinger()
    {
    }
    void Curiosity()
    {
        std::default_random_engine generator;
        std::uniform_int_distribution<int> distribution(0,m_size);
        if(*cats[distribution(generator)] == Cat::State::ALIVE)
        {
            std::cout<<"You Cat is alive and still kicking" <<std::endl;
        }
    }
private:
    std::vector<Cat *> cats;
    size_t m_size;
};
int main()
{
    int size;    
    std::cout<<"How Big is Your Example Space ?";
    std::cin>>size;
    Schrödinger your(size);
    your.Curiosity();
    return 0;

}

¿Puedes acceder this->m_deaddespués delete this?
Bryan Chen

@BryanChen: faltaba un retorno. Gracias por señalarlo :-)
Abhijit

öno parece ser un símbolo válido en C ++. Quizás reemplazarlo con oe.
Ruslan

13

C

Se ejecuta en Linux.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void f(char x) {
    if(sleep(1)==x) system("killall cat");
}
int main() {
    char x; // uninitialised
    system("cat /dev/urandom &");
    f(x);
    return 0;
}

Probabilidad de matar al gato: 1/256 ( sleep(1)devuelve 0, por lo que se matará si xes cero).

Como beneficio adicional, mata a todos los gatos que se ejecutan actualmente en su sistema.


Si odias tanto a los gatos, te presento:

El ciempiés gato (Bash)

echo "Hello World"|cat|cat|cat

Basado en el hecho de que, en The Human Centipede (Primera secuencia) , murieron los tres perros del ciempiés, y dos de cada tres personas del ciempiés humano murieron, calculo que la probabilidad de matar a un gato es 5/6.


Cat Centipede es realmente divertido
Sarge Borsch

El ciempiés gato debería ser la respuesta "real".
Ismael Miguel

@Ismael Miguel Probablemente tengas razón, he eliminado el código C. Al principio estaba destinado a ser una broma, pero luego me di cuenta de que podía reformularlo para que fuera una respuesta real.
ace_HongKongIndependence

Puedes mantener tu código C, lo tengo y no tengo nada en contra. Solo pensé que la versión bash era más adecuada como respuesta.
Ismael Miguel

@Ismael Miguel Nah, ese código C fue bastante estúpido de todos modos
ace_HongKongIndependence

9

JavaScript

~"cat".localeCompare("dead")
  ? "Cat is dead"
  : "Cat is fine"

Ejecución:

  • Chrome: resultados en"Cat is fine"
  • Firefox: resultados en"Cat is dead"

Explicación:

15.5.4.9 String.prototype.localeCompare (eso)

Las dos cadenas se comparan de una manera definida por la implementación

Citando a Glenn Randers-Pehrson, la probabilidad no es determinable por el programa; depende de la elección del navegador, que realiza el usuario.


No es reproducible en FF 27. ¿En qué versión está probando?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

-1: el comportamiento indefinido y el comportamiento definido por la implementación son completamente diferentes.
whitequark

2
@whitequark No, no lo son. Es una función definida con un resultado indefinido. Ergo comportamiento indefinido.
George Reith

1
@whitequark No veo ninguna C aquí. En lo que respecta a JavaScript, ¿JavaScript tiene un comportamiento indefinido? Parece que el comportamiento definido por la implementación es aceptable.
George Reith

1
@whitequark nadie más está confundido. Una palabra es una palabra, no necesito un comité que me diga lo que significa.
George Reith

9
int foo() {}

void main() {
    int x = foo();
}

Leer un valor de función que se supone que devuelve un valor da como resultado un comportamiento indefinido. Ahora, es obvio, [cita requerida] que "Cada vez que alcanzas un comportamiento indefinido, Dios mata a un gatito". Usando esto concluimos:

  • Probabilidad de alcanzar un comportamiento indefinido: 100%
  • Probabilidad es tu gatito que dios mató - 1/200 000 000 mira por qué
  • Entonces la probabilidad es 0.0000005%

Se puede extender fácilmente por bucle para exterminar a todos los gatos del mundo.


55
Su probabilidad es 100 veces demasiado alta (200 millones de gatos, no 2 millones).
ugoren

Tengo en porcentajes. :)
Petr

1
Está en porcentajes, y todavía es 100 veces más alto.
ugoren

Tienes razón, al parecer ya no puedo leer números.
Petr

Esto es incorrecto. UB solo se invoca si la persona que llama intenta utilizar el valor de retorno. De lo contrario, es completamente legal y está bien definido salirse del final de una función con un tipo de retorno no nulo.
R ..

5

Java (recolección de basura)

Aunque el código puede invocar System.gc () no se asegura de que el recolector de basura recolecte todos los objetos no utilizados. Por lo tanto, para el siguiente código, es impredecible si el gato será asesinado o no.

public class KillTheCat {
    public static void main(String[] args) throws InterruptedException {
        KillTheCat cat = new KillTheCat();
        cat = null;
        System.gc();
        System.out.println("Cat is still alive.");
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("Cat has been killed.");
        System.exit(0);
    }
}

La probabilidad no se puede calcular.

Tenga en cuenta que todavía existe la posibilidad de que el gato sea "revivido" si hay un cambio de contexto en el hilo del GC después de sysout y antes de System.exit (0) pero preferí no cubrirlo para mantener el concepto más simple.


1
Esto no está bien. Este código tal como está escrito casi siempre imprimirá ambos. Mejor sería agregar System.out.close()después de la System.out.println("Cat is still alive.");línea.
durron597

Según tengo entendido, "casi siempre" coincide con el aspecto impredecible de la pregunta.
user3001267

5

¿Alguien ha pensado en matar realmente (a) cat?

[ $[ $RANDOM % 6 ] == 0 ] && rm /bin/cat || echo Meow

Probabilidad de catmorir

Para la probabilidad ... supongo que necesitamos distinguir algunos casos:

  1. Usuario de Windows : Probablemente no podrá ejecutarlo. La probabilidad de morir cats es muy baja, se puede suponer con seguridad que es cero. Si tiene instalado Cygwin, contará como usuario de Unix.
  2. Usuario de Unix, que se ejecuta sin privilegios de root : matarlo catfallará.
  3. Usuario de Unix, que se ejecuta con privilegios de root : aunque cada llamada solo matará cats con una probabilidad de 1/6, lo más probable es que la repita hasta que ocurra algo inesperado. Sin pérdida de generalidad, supongo catque definitivamente morirá.

La probabilidad general depende de cómo se mezclan los usuarios y es difícil de determinar. Pero seguramente podemos decir: Windows es un lugar seguro para los gatitos.

Prueba de obediencia a las reglas

Ningún animal puede ser dañado en la producción de su respuesta.

Esto no mató a los animales, la respuesta está aprobada por la American Humane Association .

$ file `which cat`
/bin/cat: Mach-O 64-bit executable x86_64

demuestra claramente que catno es un animal (siempre y filecuando no conozca ningún tipo de herencia de tipo de archivo oculto).


5

C

Si el nombre de tu gato es demasiado largo, muere. getscausa muertes de gatos, junto con otros problemas.

#include <stdio.h>
#include <stdbool.h>

/* Stores instances of cats. */
struct cat {
    /* 6 bytes are more than enough. */
    char name[6];

    /* Stores whether your cat is dead. */
    bool dead;
};

int main(void) {
    /* This is your cat. */
    struct cat your_cat;
    /* It lives. */
    your_cat.dead = false;
    /* Determine its name. */
    printf("Your cat name: ");
    gets(your_cat.name);

    /* Output the cat state. */
    const char *state = your_cat.dead ? "dead" : "alive";
    printf("Your cat, %s, is %s.\n", your_cat.name, state);

    return your_cat.dead;
}

4

Haskell

import Acme.Missiles
import System.IO.Unsafe
main = print (unsafePerformIO launchMissiles, undefined)

Aquí, aplicamos unsafePerformIOa una acción que tiene efectos secundarios observables . Ese es siempre un comportamiento indefinido, al menos así es el orden de los efectos. Entonces, o el programa se bloqueará por primera vez al tratar de evaluar undefined(irónicamente, ese no es un comportamiento indefinido: nunca debe arrojar un valor que permita que el programa continúe con otra cosa), o de hecho incurrirá en una seria internacional efectos secundarios. En ese caso, la probabilidad de supervivencia es de solo 0.001% .

Probabilidad de matar al gato así: 49.9995%.


3

Jue

Dado que la pregunta permite un lenguaje que no tiene un comportamiento indefinido siempre que el efecto sea similar, elijo Thue por su no determinismo al elegir qué regla ejecutar cuando hay más de 1 regla que se puede aplicar en el actual estado.

El programa se alimentará al controlador para un horno de microondas, dentro del cual está mi gato. La puerta del horno de microondas está cerrada y reforzada por una cremallera. La salida del programa decidirá si el horno de microondas comienza a microondas o no al gato.

  • Si la salida es 0, comenzaremos el experimento sobre el efecto de la exposición prolongada de microondas en mamíferos vivos (que actualmente no se ha investigado lo suficiente).
  • Si la salida es 1, estaremos satisfechos con el hecho de que el gato acaba de perder una de sus 9 vidas y lo dejó salir.

i::=~0
i::=~1
::=
i

La probabilidad de matar al gato depende de la implementación del intérprete, pero digamos que es del 50%. Entonces la probabilidad de que el gato muera es 0.5 .


No determinado no significa no definido
Score_Under

@Score_Under: ¿Cuál es tu punto?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

La pregunta solicita un comportamiento indefinido, que implica aprovechar el comportamiento de un lenguaje que se compilará y ejecutará, pero no tiene especificaciones sobre lo que realmente debería hacer. Enganchar cosas, Math.random()por ejemplo, no es un comportamiento indefinido, solo un comportamiento impredecible.
Score_Under

1
@Score_Under: En la pregunta3. If you choose a language that doesn't have undefined behavior, use something similar.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1

Java

Según las especificaciones java.util.Date tendrá un comportamiento indefinido. Así que prueba tu suerte:

import java.util.Date;

public class App3
{
    public static void main (String args[])
    {
        String aliveOrDead;
        Date d = new Date(-1000,-1000,-1000);
        aliveOrDead = (d.getTime()<0)? "dead" : "alive";
        System.out.println("The cat is:" +aliveOrDead );
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.