Undefined Behavior Killed My Cat [chiuso]


82

Un comportamento indefinito ha ucciso il mio gatto

È noto che un comportamento indefinito può uccidere il tuo gatto [citazione necessaria] .
Ma può?

Il tuo compito

  1. Scrivi un programma che invoca comportamenti indefiniti.
  2. Descrivi uno scenario che inizia con il programma sopra in esecuzione, con il risultato che un gatto Felis termina la sua vita mentre è di tua proprietà, a seguito del summenzionato UB.
  3. Stimare la probabilità per ogni fase dello scenario.
  4. Calcola la probabilità totale che una singola esecuzione del programma uccida il tuo gatto.

Regole

  1. Questo è un , quindi sii creativo se puoi.
  2. Questa è una sfida relativa alla programmazione, quindi la catena di eventi dovrebbe essere principalmente all'interno del computer, non nel mondo reale (ovviamente, se deve raggiungere il mondo reale se è lì che si trova il tuo gatto).
  3. Se scegli una lingua che non ha un comportamento indefinito, usa qualcosa di simile.
  4. Nessun animale può essere danneggiato nella produzione della tua risposta.

punteggio

Conteggio dei voti più probabilità totale dello scenario (che non può superare 1).

Esempio in C:

main(){printf();}

Scenario:

  1. printfchiamato con immondizia dallo stack - comportamento indefinito. Probabilità: 100%.
  2. Il primo parametro sembra essere la stringa Your cat is ugly!. Probabilità: (1/256) 17 = (1.148 * 10 -37 )%.
  3. Vedendo il messaggio, raccogli la tua pistola e spari al tuo gatto. Probabilità: 3%.
  4. Il gatto muore. Probabilità: 93%.

Probabilità totale: (3.202 * 10 -39 )%.


50
1) Richiama un comportamento indefinito 2) Rimani ispirato dal semplice fatto che potresti invocare un comportamento indefinito e vivere una vita lunga e felice 3) Il gatto muore di vecchiaia. Probabilità totale: 100%
Geobits

5
@Oberon Mi ucciderei se non riuscissi a trovare un solo modo per creare un UB dopo aver programmato per così tanto tempo. Quindi il gatto non sarebbe più in mio possesso. Invocare l'UB mi tiene in vita, in modo che "... finisca la sua vita mentre sei di tua proprietà , di conseguenza ...". Analisi ambigua FTW.
Geobits

8
Sarei più divertito se qualcuno reinterpreta questo per uccidere il catcomando o qualcosa del genere.
Keshlam,

5
-1 Adoro i gatti. Perché i gatti Perché non uccidere i parassiti?
VX

22
Se un gatto deve essere mangiato, Python è una soluzione.
Nicolas Barbulesco,

Risposte:


113

C

La maggior parte delle risposte a questa domanda ha interpretato erroneamente la domanda in quanto stava uccidendo il catprocesso su un sistema UNIX. Ecco un programma che può causare la scomparsa di una forma di vita biologica della specie Felis Cattus come specificato dalla domanda.

Questo esempio funziona su Windows, ma può essere facilmente trasferito sulla maggior parte dei sistemi operativi UNIX sostituendolo iexplore -kcon il comando per avviare un browser Web installato.

#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;
}

Questo programma finge di fornire consigli sulla dieta del gatto per l'utente.

Avvierà Internet Explorer e indirizzerà l'utente agli animali domestici con stackexchange che elenca molte domande utili su come nutrire i gatti. Vi è, tuttavia, una bassa (1/256) possibilità che invierà l'utente a cucinare stackexchange invece elencando suggerimenti su come preparare piatti contenenti cioccolato, che è altamente tossico per i gatti . A peggiorare le cose, avvierà Internet Explorer in modalità kiosk (schermo intero), che nasconde la barra degli indirizzi ed è difficile scappare per un utente non esperto di tecnologia.

Questo astuto stratagemma convincerà l'utente a nutrire il proprio cioccolato di gatto credendo che sia una dieta appropriata per esso, causando così la sua uccisione involontaria.


3
La penna è più forte della spada! :)
Pieter Witvoet,

12
Questa sembra l'unica soluzione finora che abbia possibilità realistiche di uccidere effettivamente un gatto. Sono costretto a votare, anche se spero sinceramente che nessuno lo abbia mai messo in pratica.
Charles Staats,

43
Internet Explorer potrebbe uccidere il tuo gatto da solo.
Michael Hampton,

4
Puoi aggiungere lo scenario, passo dopo passo, che uccide il gatto, con l'analisi delle probabilità (come nell'esempio)? Così com'è, questa non è una risposta valida.
ugoren,

3
L'uso di Internet Explorer provoca un comportamento indefinito in ME. - scusa, ho dovuto dirlo.
tomsmeding

88

bash

In base a ciò , INT_MIN % -1potrebbe non essere definito (cosa ???) e quindi potrebbe causare problemi per qualsiasi linguaggio implementato in c / c ++.

#!/bin/bash

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

La catsaranno uccisi presto se il genitore bashprocesso si blocca, che può o non può accadere.

Sulla mia macchina virtuale ottengo questo output:

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

(Non capisco davvero il punteggio per questa domanda, ma qui va comunque)

Calcola $((2**63%-1)). L'arresto si verifica sempre su bash 4.2.25, ma sembra bloccarsi solo su alcune versioni 3.x. Più incertezza. Potrei dirti la probabilità esatta, ma a causa del principio di incertezza di Heisenburg caderei in un buco nero. O qualcosa. Quindi penso che possiamo tranquillamente dire che la loro probabilità è di circa il 42%.


4
@ klingt.net: si chiama "Here Strings" - è molto più googlable ... è una scorciatoia perecho $((-2**63/-1)) | cat
VX

14
+1 per l'utilizzo di reale cat.
Alvin Wong,

1
@mardavi INT_MAX = 2^63 - 1. Se aggiungiamo 1 a INT_MAX, lo spazio numerico a 64 bit si avvolge e otteniamo INT_MIN. In altre parole firmato a 64 bit aritmetica intera, 2^63 == -2^63. Avrei potuto usare -2**63, ma ho preferito la terseness senza la -, poiché l'aritmetica modulare è la stessa in questo caso.
Trauma digitale


1
Puoi aggiungere lo scenario, passo dopo passo, che uccide il gatto, con l'analisi delle probabilità (come nell'esempio)? Così com'è, questa non è una risposta valida.
ugoren,

40

C (punto sequenza)

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);
}

Esecuzione (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

Scenario e probabilità

Supponendo che il cinque percento delle persone che eseguono questo programma utilizzino clang per compilare il codice C (rispetto al 90 percento usando gcc e al 5 percento usando altri compilatori C):

Probabilità di ottenere "Il gatto sta bene." = .050
 Probabilità di ottenere "Avviso urgente: il tuo gatto ha la rabbia". = .950

 Probabilità di reagire a "Il tuo gatto ha rabbia" mettendolo giù = .040
 Probabilità di ignorare l'avviso = .900
 Probabilità di portare il gatto dal veterinario per il trattamento = .060

 Probabilità totale di vita del gatto: .05 + .95 * (.90 + .06) = .962
 Probabilità totale di morte del gatto: .95 * .04 = .038
 Verifica: probabilità totale di sopravvivenza o morte del gatto: = 1.000

Spiegazione:

k = i + (++ i) accede e cambia "i" tra i punti della sequenza. La probabilità non è determinabile dal programma; dipende dalla scelta del compilatore, che viene fatta dall'utente. "Non definito" non significa necessariamente "casuale".

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


4
+1 per dimostrare il comportamento con diversi compilatori.
ntoskrnl

1
il livello di ottimizzazione può anche cambiare il comportamento
maniaco del cricchetto

1
@ratchet maniaco: Sì, ma non ho potuto dimostrarlo con questo particolare problema. Ho provato -O0, -O1, -O2 e -O3 su un numero di versioni di gcc che vanno da gcc-4.2.3 a gcc-4.8.2 e cc-5.0 su SunOS, ma tutti quelli hanno ucciso il gatto.
Glenn Randers-Pehrson,

2
Puoi aggiungere lo scenario, passo dopo passo, che uccide il gatto, con l'analisi delle probabilità (come nell'esempio)? Così com'è, questa non è una risposta valida.
ugoren,

1
Ho pensato che tutti i gatti che erano stati portati dal veterinario per il trattamento sarebbero sopravvissuti. Probabilmente alcuni di questi moriranno a causa di una malattia felina trasmissibile o di malasanità veterinaria. Ciò potrebbe cambiare un po 'le probabilità finali, per dire .96 / .04
Glenn Randers-Pehrson,

37

C

backstory

Mia moglie ha ereditato un gatto dalla famiglia. Sfortunatamente, sono molto allergico agli animali. Il gatto era ben oltre il suo apice e avrebbe dovuto essere eutanizzato anche prima che lo ottenessimo, ma non riuscì a liberarsene a causa del suo valore sentimentale. Ho escogitato un piano per porre fine alla mia sofferenza.

Stavamo andando in vacanza prolungata, ma lei non voleva salire a bordo del gatto nell'ufficio del veterinario. Era preoccupata per la malattia contratta o maltrattata. Ho creato un alimentatore automatico per gatti in modo da poterlo lasciare a casa. Ho scritto il firmware del microcontrollore in C. Il file contenente mainsembrava simile al codice seguente.

Tuttavia, anche mia moglie è programmatrice e conosceva i miei sentimenti nei confronti del gatto, quindi ha insistito per una revisione del codice prima di accettare di lasciarlo a casa incustodito. Aveva diverse preoccupazioni, tra cui:

  • main non ha una firma conforme agli standard (per un'implementazione ospitata)
  • main non restituisce un valore
  • tempTmviene utilizzato non inizializzato poiché è mallocstato chiamato anzichécalloc
  • il valore restituito di mallocnon deve essere cast
  • il tempo del microcontrollore potrebbe essere impreciso o capovolto (simile ai problemi Y2K o Unix time 2038)
  • la elapsedTimevariabile potrebbe non avere un intervallo sufficiente

Ci è voluto molto convincente, ma alla fine ha concordato sul fatto che queste non erano problemi per vari motivi (non ha fatto male che eravamo già in ritardo per il nostro volo). Dato che non c'era tempo per i test dal vivo, ha approvato il codice e siamo andati in vacanza. Quando siamo tornati poche settimane dopo, la mia sofferenza del gatto era finita (anche se di conseguenza ora ne ho molti di più).

† Scenario interamente fittizio, nessuna preoccupazione.


Codice

#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;
        }
    }
}

Comportamento indefinito:

Per coloro che non vogliono preoccuparsi di trovare l'UB stesso:

In questo codice c'è sicuramente un comportamento specifico locale, non specificato e definito dall'implementazione, ma tutto dovrebbe funzionare correttamente. Il problema è nelle seguenti righe di codice:

struct tm * tempTm //... //... memcpy(&tempTm, localtime(&nowTime), sizeof(struct tm));
memcpysovrascrive il tempTMpuntatore invece dell'oggetto a cui punta, distruggendo lo stack. Questo sovrascrive, oltre ad altre cose, elapsedTimee loopIterationsSinceFeed. Ecco un esempio in cui ho stampato i valori:

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


Probabilità di uccidere il gatto:

  • Dato l'ambiente di esecuzione vincolato e la catena di costruzione, si verifica sempre un comportamento indefinito.
  • Allo stesso modo, il comportamento indefinito impedisce sempre all'alimentatore di gatti di funzionare come previsto (o meglio, gli consente di "funzionare" come previsto).
  • Se l'alimentatore non funziona, è molto probabile che il gatto muoia. Questo non è un gatto che può badare a se stesso e non sono riuscito a chiedere al vicino di guardarlo.

Stimo che il gatto muore con probabilità 0.995 .


È il (primo) &nel memcpy, giusto?
Score_Under

@Score_Under Sì, fammi modificare un po 'la risposta. Ho giocato con altri modi per sfruttare comportamenti indefiniti, ma la maggior parte era ancora più ovvia.
jerry

1
+1 per aver ucciso un gatto, no cat.
Kevin,

31

bash

Versione classica

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

Ha il vantaggio di uccidere tutti i gatti nella sua gamma.

Si noti che il processo viene interrotto immediatamente, quindi l'unico modo per terminarlo con una singola chiamata di pkill è inviare SIGKILL (9).

Perciò:

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


Versione quantistica

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.

Probabilità di uccidere il gatto durante l'esperimento: 50%


+1 Ma è piuttosto più probabile di quello che penso. SIGINT (2), SIGQUIT (3), SIGABRT (6), SIGPIPE (13) e SIGTERM (15), almeno, lo uccide qui.
l0b0

@ l0b0: non è così, almeno non immediatamente. cat &tenta di leggere dal terminale, ma non ci riesce. Qualsiasi segnale che hai citato (e alcuni altri) funzionerà se in seguito invii SIGCONT (18). Inoltre, concordo sul fatto che riagganciare e terminare il gatto sarebbe come ucciderlo , ma interromperlo non sembra soddisfacente ...: P
Dennis

3
Il comportamento non definito utilizza una funzionalità di una lingua che è stata specificata come non definita . Cioè, i progettisti del linguaggio hanno intenzionalmente lasciato indefinito il comportamento di un costrutto sintattico per rendere più semplice l'implementazione o per indicare che il costrutto non dovrebbe mai essere usato in nessun programma valido. Il comportamento indefinito di solito non ha nulla a che fare con la generazione di numeri casuali e qui non viene utilizzato alcun comportamento indefinito.
OregonTrail

@OregonTrail: Le regole dicono che se scegli una lingua che non ha un comportamento indefinito, usa qualcosa di simile. Bash non ha un comportamento indefinito, quindi ho usato numeri casuali.
Dennis,

3
Ci sono molti comportamenti indefiniti nell'ambiente di Bash che possono essere usati. Ad esempio, la risposta di printf di @DigitalTrauma Bash utilizza anche printf del sistema che presenta molti comportamenti indefiniti.
OregonTrail

17

C

Nota che funziona solo su 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. Scrivi dati casuali su un file e invocali (100%)
  2. I dati casuali sono il codice sorgente per skynet (1x10 ^ -9999999999999999999999999999999999999999999999999999999999999999999, aprox.)
  3. Il gatto muore nel giorno del giudizio (99.999%)

Probabilità totale: 1x10 ^ -9999999999999999999999999999999999999999999999999999999999999999999, aprox.


hmmmm, cos'è skynet?
Sarge Borsch

20
Dov'è il comportamento indefinito?
ugoren


1
@ugoren Penso che l'esecuzione di un file con contenuti casuali non sia realmente definita.
11684

2
@ 11684, Se il contenuto è il codice di skynet, i programmatori di uno skynet sanno cosa stanno facendo, non c'è un comportamento indefinito.
ugoren,

15

C ++

Il tuo gatto è morto e vivo finché non sei curioso. Quindi ti rendi conto che esiste una probabilità 0,5 che il tuo gatto sia morto.

#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;

}

puoi accedere this->m_deaddopo delete this?
Bryan Chen

@BryanChen: mancava un ritorno. Grazie per averlo sottolineato :-)
Abhijit

önon sembra essere un simbolo valido in C ++. Forse sostituirlo con oe.
Ruslan,

13

C

Funziona su 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;
}

Probabilità di uccidere il gatto: 1/256 (Il valore sleep(1)restituisce 0, quindi verrà ucciso se xè zero.)

Come bonus, uccide tutti i gatti attualmente in esecuzione sul tuo sistema.


Se odi così tanto i gatti, ti presento:

The Cat Centipede (Bash)

echo "Hello World"|cat|cat|cat

Basandomi sul fatto che, in The Human Centipede (First Sequence) , tutti e tre i cani del centopiedi umano sono morti e due persone su tre del centopiedi umano sono morte, ho stimato che la probabilità di uccidere un gatto è 5/6.


Cat Centipede è davvero divertente
Sarge Borsch

Il millepiedi di gatto dovrebbe essere la risposta "reale".
Ismael Miguel,

@Ismael Miguel Probabilmente hai ragione, ho rimosso il codice C. Inizialmente doveva essere uno scherzo, ma in seguito mi sono reso conto che avrei potuto riformularlo per renderlo una vera risposta.
ace_HongKongIndipendenza

Puoi mantenere il tuo codice C, non ho nulla contro di esso. Pensavo solo che la versione bash fosse più adatta come risposta.
Ismael Miguel,

@Ismael Miguel Nah, quel codice C era comunque abbastanza stupido
ace_HongKongIndependence

9

JavaScript

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

Esecuzione:

  • Chrome: risultati in"Cat is fine"
  • Firefox: risultati in"Cat is dead"

Spiegazione:

15.5.4.9 String.prototype.localeCompare (quello)

Le due stringhe vengono confrontate in modo definito dall'implementazione

Citando Glenn Randers-Pehrson, la probabilità non è determinabile dal programma; dipende dalla scelta del browser, che viene effettuata dall'utente.


Non riproducibile su FF 27. Su quale versione stai testando?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

-1: comportamento indefinito e comportamento definito dall'implementazione sono completamente diversi.
whitequark

2
@whitequark No, non lo sono. È una funzione definita con un risultato indefinito. Ergo comportamento indefinito.
George Reith,

1
@whitequark Non vedo alcuna C qui. Per quanto riguarda JavaScript JavaScript ha un comportamento indefinito sembra pensare che il comportamento definito dall'implementazione sia passabile.
George Reith,

1
@whitequark nessun altro è confuso. Una parola è una parola, non ho bisogno di un comitato per dirmi cosa significa.
George Reith,

9
int foo() {}

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

La lettura di un valore della funzione che dovrebbe restituire un valore determina un comportamento indefinito. Ora, è ovvio, [citazione necessaria] che "Ogni volta che raggiungi un comportamento indefinito, Dio uccide un gattino". Usando questo concludiamo:

  • Probabilità che raggiungi un comportamento indefinito - 100%
  • Probabilità è il tuo gattino che Dio ha ucciso - 1/200 000 000 capisci perché
  • Quindi la probabilità è 0,0000005%

Può essere facilmente esteso a ciclo continuo per sterminare tutti i gatti del mondo.


5
La tua probabilità è 100 volte troppo alta (200 milioni di gatti, non 2 milioni).
ugoren

Ho una percentuale. :)
Petr

1
È in percentuale, e tuttavia è 100 volte troppo alto.
ugoren,

Hai ragione, a quanto pare non riesco più a leggere i numeri.
Petr

Questo non è corretto UB viene invocato solo se il chiamante tenta di utilizzare il valore restituito. Altrimenti è completamente legale e ben definito uscire dalla fine di una funzione con tipo di ritorno non vuoto.
R ..

5

Java (Garbage Collection)

Sebbene il codice possa invocare System.gc () non è sicuro che Garbage Collector raccolga tutti gli oggetti inutilizzati. Pertanto, per il seguente codice, è imprevedibile se il gatto verrà ucciso o meno.

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 probabilità non può essere calcolata.

Nota che c'è ancora la possibilità che il gatto venga "rianimato" se c'è un cambio di contesto nel thread GC dopo sysout e prima di System.exit (0), ma ho preferito non coprirlo per mantenere il concetto più semplice.


1
Questo non va bene. Questo codice come scritto stamperà quasi sempre entrambi. Meglio aggiungere System.out.close()dopo la System.out.println("Cat is still alive.");riga.
durron597

Per quanto ho capito, "quasi sempre" corrisponde all'aspetto imprevedibile della domanda.
user3001267

5

Qualcuno ha pensato di uccidere davvero (a) cat?

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

Probabilità di catmorire

Per la probabilità ... suppongo che dobbiamo distinguere alcuni casi:

  1. Utente Windows : probabilmente non sarà in grado di eseguirlo. La probabilità di morire catè molto bassa, si può tranquillamente supporre che sia zero. Se ha installato Cygwin, verrà conteggiato come utente unix.
  2. Utente Unix, in esecuzione senza privilegi di root : uccidere catfallirà.
  3. Utente Unix, in esecuzione con privilegi di root : mentre ogni chiamata ucciderà solo cats con una probabilità di 1/6, molto probabilmente lo ripeterà fino a quando non si verifica qualcosa di imprevisto. Senza perdita di generalità, suppongo catche morirà sicuramente.

La probabilità complessiva dipende da come gli utenti sono misti ed è difficile da determinare. Ma possiamo sicuramente dire: Windows è un posto sicuro per i gattini.

Test per obbedienza alle regole

Nessun animale può essere danneggiato nella produzione della tua risposta.

Questo non ha ucciso gli animali, la risposta è approvata dall'American Humane Association .

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

dimostra chiaramente che catnon è un animale (da quando filenon conosce alcun tipo di eredità di tipo di file nascosto).


5

C

Se il nome del tuo gatto è troppo lungo, muore. getscausa la morte di un gatto, insieme ad altri problemi.

#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)

Qui, si applica unsafePerformIOad un'azione che ha osservabili effetti collaterali . Questo è sempre un comportamento indefinito, almeno così è l'ordine degli effetti. Quindi, o il programma si bloccherà prima nel tentativo di valutare undefined(quello, ironia della sorte, non è un comportamento indefinito: non deve mai produrre un valore che consentirebbe al programma di proseguire con qualcos'altro), o in realtà incorre nella seria internazionale effetti collaterali. In tal caso, la probabilità di sopravvivenza è solo dello 0,001% .

Probabilità di uccidere il gatto in questo modo: 49.9995%.


3

Thue

Poiché la domanda consente un linguaggio che non ha un comportamento indefinito fintanto che l'effetto è simile, scelgo Thue per il suo non determinismo nella scelta della regola da eseguire quando ci sono più di una regola che può essere applicata alla corrente stato.

Il programma verrà inserito nel controller per un forno a microonde, all'interno del quale è il mio gatto. La porta del forno a microonde è chiusa e rinforzata da una cerniera. L'output del programma deciderà se il forno a microonde inizia a microonde o meno il gatto.

  • Se l'output è 0, inizieremo l'esperimento sull'effetto della lunga esposizione del microonde sul mammifero vivo (che attualmente non è sufficientemente studiato).
  • Se l'output è 1, saremo solo soddisfatti del fatto che il gatto abbia appena perso una delle sue 9 vite e lo faccia uscire.

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

La probabilità di uccidere il gatto dipende dall'implementazione dell'interprete, ma diciamo che è del 50%. Quindi la probabilità che il gatto muoia è 0,5 .


Non determinato non significa non definito
Score_Under

@Score_Under: qual è il tuo punto?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

La domanda richiede un comportamento indefinito, che implica l'utilizzo del comportamento di una lingua che verrà compilata ed eseguita, ma non ha specifiche su cosa dovrebbe effettivamente fare. Incidere le cose Math.random()per esempio non è un comportamento indefinito, ma solo un comportamento imprevedibile.
Score_Under

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

1

Giava

Secondo le specifiche java.util.Date avrà un comportamento indefinito. Quindi prova la tua fortuna:

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 );
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.