Невизначена поведінка вбила мого кота [закрито]


82

Невизначена поведінка вбила мого кота

Добре відомо, що невизначена поведінка може вбити вашу кішку [потрібна цитата] .
Але чи може це?

Ваше завдання

  1. Напишіть програму, яка викликає невизначене поведінку.
  2. Опишіть сценарій, який починається з запуску вищевказаної програми, в результаті чого катус Felis закінчує своє життя, перебуваючи у вашій власності, внаслідок вищезгаданого UB.
  3. Оцініть ймовірність для кожного етапу сценарію.
  4. Обчисліть загальну ймовірність того, що один запуск програми вбив вашу кішку.

Правила

  1. Це , тому будьте творчі, якщо зможете.
  2. Це завдання, пов’язане з програмуванням, тому ланцюжок подій має знаходитися здебільшого за комп’ютером, а не в реальному світі (звичайно, якщо доведеться дійти до реального світу, якщо там знаходиться ваша кішка).
  3. Якщо ви вибираєте мову, яка не має визначеної поведінки, використовуйте щось подібне.
  4. Жодна тварина не може завдати шкоди під час створення вашої відповіді.

Оцінка балів

Підрахунок голосів плюс загальна ймовірність сценарію (що не може перевищувати 1).

Приклад в C:

main(){printf();}

Сценарій:

  1. printfдзвонили зі сміттям зі стека - невизначена поведінка. Ймовірність: 100%.
  2. Першим параметром буває рядок Your cat is ugly!. Ймовірність: (1/256) 17 = (1,148 * 10 -37 )%.
  3. Побачивши повідомлення, ви піднімаєте пістолет і стріляєте в кішку. Ймовірність: 3%.
  4. Кішка гине. Ймовірність: 93%.

Повна ймовірність: (3.202 * 10 -39 )%.


50
1) Закликайте до невизначеної поведінки 2) Залишайтесь натхненним самим фактом, що ви можете викликати невизначену поведінку і прожити довге щасливе життя 3) Кішка помирає від старості. Повна ймовірність: 100%
Геобіт

5
@Oberon Я вбив би себе, якби не міг придумати єдиний спосіб створити UB після програмування так довго. Тоді кота вже не було б у мене. Закликання УБ тримає мене в живих, так що "... закінчення його життя, перебуваючи у вашій власності , як результат ...". Неоднозначний розбір FTW.
Геобіт

8
Мені було б більше цікаво, якщо хтось повторно тлумачить це, щоб вбити catкоманду чи щось подібне.
кешлам

5
-1 Я люблю котів. Чому коти? Чому б не убити шкідників?
VX

22
Якщо кішку потрібно їсти, Python - це рішення.
Ніколя Барбулеско

Відповіді:


113

С

Більшість відповідей на це запитання неправильно трактували питання в тому, що це вбивало catпроцес у системі UNIX. Ось програма, яка може спричинити занепад біологічної форми життя виду Felis Cattus, що конкретизується питанням.

Цей приклад працює в Windows, але його можна легко перенести в більшість операційних систем UNIX, замінивши iexplore -kна команду запуску встановленого веб-браузера.

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

Ця програма робить вигляд, що надає користувачеві поради щодо дієти котів.

Він запустить Internet Explorer і скеровує користувача до домашніх тварин, у якому перелічено безліч корисних питань про те, як годувати котів. Однак є низький (1/256) шанс, що він надішле користувача на приготування їжі, замість того, щоб перелічити поради, як приготувати страви, що містять шоколад, який є високотоксичним для котів . Що ще гірше, він запустить Інтернет-провідник у режимі кіоску (повноекранний), який приховує адресний рядок і з нього важко вийти з-за нетехнологічного користувача.

Цей розумний хижак примусить користувача до годування котячим шоколадом, вважаючи, що це правильна дієта для цього, тим самим змусивши їх ненавмисно вбити.


3
Перо могутніше меча! :)
Пітер Вітвоет

12
Це схоже на єдине на сьогодні рішення, яке має будь-який реалістичний шанс фактично вбити кота. Я змушений подати заяву, хоча щиро сподіваюся, що ніхто ніколи насправді не реалізує це.
Чарльз Стейтс

43
Internet Explorer може вбити вашу кішку самостійно.
Майкл Хемптон

4
Чи можете ви додати сценарій, крок за кроком, який вбиває кота, за допомогою аналізу ймовірності (як у прикладі)? Насправді це неправдива відповідь.
угорен

3
Використання Internet Explorer індукує не визначену поведінку в ME. - вибачте, мав це сказати.
tomsmeding

88

Баш

Згідно з цим , INT_MIN % -1може бути, а може і не бути визначеним (що таке ???) , і так може виникнути проблеми для будь-якої мови, реалізованої в c / c ++.

#!/bin/bash

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

catБуде убитий рано , якщо батьківський bashпроцес відбувається збій, який може або не може відбутися.

У моєму VM я отримую такий вихід:

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

(Я не дуже розумію оцінку за це питання, але тут все одно)

Обчисліть $((2**63%-1)). Збій завжди трапляється на bash 4.2.25, але, схоже, просто зависає на деяких версіях 3.x. Більше невизначеності. Я міг би сказати вам точну ймовірність, але через принцип невизначеності Гейзенбурга я тоді впав би в чорну діру. Або щось. Тому я думаю, що ми можемо з упевненістю сказати, що ймовірність становить приблизно 42%.


4
@ klingt.net: Він називається "Here Strings" - він набагато більш googlable ... це ярлик дляecho $((-2**63/-1)) | cat
VX

14
+1 за використання реального cat.
Елвін Вонг

1
@mardavi INT_MAX = 2^63 - 1. Якщо ми додамо 1 до INT_MAX, простір з 64-бітним числом обертається навколо, і ми отримуємо INT_MIN. Іншими словами , в підписаному 64 - бітної цілочисельний арифметики, 2^63 == -2^63. Я міг би використати -2**63, але віддав перевагу лаконічності без -, оскільки модульна арифметика в цьому випадку однакова.
Цифрова травма


1
Чи можете ви додати сценарій, крок за кроком, який вбиває кота, за допомогою аналізу ймовірності (як у прикладі)? Насправді це неправдива відповідь.
угорен

40

C (точка послідовності)

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

Виконання (чи ні):

$ 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

Сценарій та ймовірність

Якщо припустити, що п’ять відсотків людей, що виконують цю програму, використовують кланг для компіляції коду С (проти 90 відсотків, що використовують gcc та 5 відсотків за допомогою інших компіляторів C):

Ймовірність отримати "Кіт добре". = .050
 Ймовірність отримати "Невідкладне повідомлення: у вашої кішки сказ". = .950

 Ймовірність реагувати на "Ваша кішка має сказ", відклавши її = .040
 Ймовірність ігнорування повідомлення = .900
 Ймовірність відвезти кота до ветеринара на лікування = .060

 Загальна ймовірність життя кота: .05 + .95 * (.90 + .06) = .962
 Повна ймовірність смерті кота: .95 * .04 = .038
 Перевірка: Загальна ймовірність того, що кішка житиме чи помирає: = 1.000

Пояснення:

k = i + (++ i) здійснює доступ і змінює "i" між точками послідовності. Ймовірність не визначається програмою; це залежить від вибору компілятора, який робить користувач. "Невизначений" не обов'язково означає "випадковий".

Дивіться https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points


4
+1 для демонстрації поведінки з різними компіляторами.
ntoskrnl

1
Рівень оптимізації може також змінити поведінку
храповик урод

1
@ratchet freak: Так, але я не міг продемонструвати це з цією конкретною проблемою. Я спробував -O0, -O1, -O2 та -O3 у кількох версіях gcc, починаючи від gcc-4.2.3 до gcc-4.8.2 та cc-5.0 на SunOS, але всіх тих, хто вбив кота.
Гленн Рендерс-Перхсон

2
Чи можете ви додати сценарій, крок за кроком, який вбиває кота, за допомогою аналізу ймовірності (як у прикладі)? Насправді це неправдива відповідь.
угорен

1
Я припускав, що всі коти, яких везуть до ветеринара, будуть жити. Ймовірно, хтось із них загине від спіймання інфекційної хвороби котів чи від ветеринарних недобросовісних дій. Це може трохи змінити остаточну ймовірність, скажімо, .96 / .04
Гленн Рендерс-Персон

37

С

Попередня історія

Моя дружина успадкувала кота від родини. На жаль, я дуже алергічний до тварин. Кішка вже минула свій розквіт і мала бути евтаназованою ще до того, як ми її отримали, але вона не могла змусити себе позбутися її через свою сентиментальну цінність. Я дозрів план , щоб закінчити мій його страждання.

Ми їхали у розширену відпустку, але вона не хотіла сідати з котом у кабінет ветеринара. Вона була стурбована тим, що вона захворіє на хворобу чи жорстоко поводиться з нею. Я створив автоматичну годівницю для котів, щоб ми могли залишити її вдома. Я написав мікропрограмне забезпечення мікроконтролера в C. Файл, що містить, mainбув схожий на код нижче.

Однак моя дружина також програміст і знала мої почуття до кота, тому наполягала на перегляді коду, перш ніж погодилася залишити його вдома без нагляду. У неї було кілька проблем, серед яких:

  • main не має стандартних підписів (для розміщеної реалізації)
  • main не повертає значення
  • tempTmвикористовується неініціалізований, оскільки mallocбув викликаний замістьcalloc
  • повернене значення mallocне повинно бути відхиленим
  • час мікроконтролера може бути неточним або перевертатись (подібно до проблем Y2K або Unix time 2038)
  • elapsedTimeзмінна не може мати достатній діапазон

Це знадобило багато переконливих, але вона, нарешті, погодилася, що тези не мали проблем з різних причин (це не завадило, що ми вже запізнилися на наш рейс). Оскільки часу на тестування в реальному часі не було, вона затвердила код і ми поїхали у відпустку. Коли ми повернулися через кілька тижнів, нещастя моєї кішки закінчилося (хоча в результаті я отримав ще багато).

† Цілком вигаданий сценарій, ніяких турбот.


Код

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

Не визначена поведінка:

Для тих, хто не хоче займатись пошуком UB:

У цьому коді безумовно є певна локальна, не визначена та визначена реалізація поведінка, але все має працювати правильно. Проблема полягає в наступних рядках коду:

struct tm * tempTm //... //... memcpy(&tempTm, localtime(&nowTime), sizeof(struct tm));
memcpyзамінює tempTMвказівник замість об'єкта, на який він вказує, розбиваючи стек. Це переробляє, крім інших речей, elapsedTimeі loopIterationsSinceFeed. Ось приклад запуску, де я роздрукував значення:

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


Ймовірність вбивства кота:

  • Враховуючи обмежене середовище виконання та ланцюжок побудови, невизначена поведінка завжди відбувається.
  • Так само невизначена поведінка завжди заважає годівниці котів працювати за призначенням (а точніше, дозволяє їй «працювати» за призначенням).
  • Якщо годівниця не працює, велика ймовірність, що кішка загине. Це не кішка, яка може побороти себе, і я не зміг попросити сусіда подивитися на це.

Я підрахував, що кішка гине з вірогідністю 0,995 .


Це (перше) &в memcpy, правда?
Score_Under

@Score_Under Так, дозвольте мені трохи відредагувати відповідь. Я розігрувався з іншими способами використання невизначеної поведінки, але більшість з них були ще більш очевидними.
Джеррі

1
+1 за вбивство кота, ні cat.
Кевін

31

баш

Класична версія

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

Має перевагу вбивати всіх котів у своєму асортименті.

Зауважте, що процес зупиняється негайно, тому єдиний спосіб закінчити його одним викликом pkill - це надіслати SIGKILL (9).

Тому:

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


Квантова версія

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.

Ймовірність вбити кота під час експерименту: 50%


+1 Але це швидше, ніж я думаю. SIGINT (2), SIGQUIT (3), SIGABRT (6), SIGPIPE (13) та SIGTERM (15), принаймні, вбиває його тут.
l0b0

@ l0b0: Це не принаймні не відразу. cat &намагається прочитати з терміналу, але не може. Будь-який із згаданих вами сигналів (та ще декількох) спрацює, якщо ви надішлете SIGCONT (18) згодом. Крім того, я погоджуюся, що повісити кота та покінчити з ним буде так само, як і вбити його, але перебивати це не здається задовільним ...: P
Dennis

3
Не визначена поведінка використовує особливість мови, яка була визначена як невизначена . Тобто дизайнери мови цілеспрямовано залишають поведінку якогось синтаксичного конструкта невизначеним, щоб полегшити реалізацію або вказати, що конструкція ніколи не повинна використовуватися в жодній дійсній програмі. Не визначена поведінка зазвичай не має нічого спільного з генерацією випадкових чисел, і тут не використовується невизначена поведінка.
OregonTrail

@OregonTrail: Правила говорять Якщо ви вибираєте мову, яка не має визначеної поведінки, використовуйте щось подібне. Bash не має визначеної поведінки, тому я використовував випадкові числа.
Денніс

3
У середовищі Баша багато невизначеної поведінки, яку можна використовувати. Наприклад, у відповіді printf @DigitalTrauma Bash також використовується система printf системи, яка має багато невизначених поведінок.
OregonTrail

17

С

Зауважте, що це працює лише на 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. Запишіть випадкові дані у файл та викликайте їх (100%)
  2. Випадкові дані стають вихідним кодом до skynet (1x10 ^ -99999999999999999999999999999999999999999999999999999999999999999999, aprox.)
  3. Кішка помирає внаслідок настання сутового дня (99,999%)

Повна ймовірність: 1x10 ^ -9999999999999999999999999999999999999999999999999999999999999999999, aprox.


hmmmm, що таке skynet?
Сардж Борщ

20
Де невизначена поведінка?
угорен


1
@ugoren Я думаю, що запуск файлу зі випадковим вмістом насправді не визначений.
11684 р.

2
@ 11684, Якщо вміст є кодом до skynet, програмісти skynet знають, що вони роблять, не визначено поведінки.
угорен

15

C ++

Ваш Кіт і мертвий, і живий, поки вам не цікаво. Тоді ви розумієте, що існує 0,5 ймовірності того, що ваш Кіт мертвий.

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

}

Ви можете отримати доступ this->m_deadпісля delete this?
Брайан Чен

@BryanChen: Відсутність повернення. ДЯКУЮ, що ви вказали на це :-)
Абхіджіт

öне здається дійсним символом у C ++. Можливо, замініть його oe.
Руслан

13

С

Працює в 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;
}

Ймовірність вбити кішку: 1/256 ( sleep(1)повертає 0, значить, вона буде вбита, якщо xдорівнює нулю.)

Як бонус, він вбиває всіх котів, які зараз працюють у вашій системі.


Якщо ви так сильно ненавидите котів, я представляю вам:

Кішка сорокоп'ята (Bash)

echo "Hello World"|cat|cat|cat

Виходячи з того, що в "Сороковок людини" (Перша послідовність) загинули всі три собаки сорока, а двоє з трьох людей сорока людини померли, я вважаю, що ймовірність вбити одну кішку становить 5/6.


Cat Centipede по-справжньому веселий
Sarge Borsch

Котяча сороконіжка повинна бути "фактичною" відповіддю.
Ісмаїл Мігель

@Ismael Miguel Ви, мабуть, праві, я видалив код C. Спочатку це мало бути жартом, але згодом я зрозумів, що можу перефразувати це, щоб зробити його справжньою відповіддю.
ace_HongKongIndependence

Ви можете зберегти свій код C, я не мав нічого проти цього. Я просто, хоча, що баш-версія була більш підходящою як відповідь.
Ісмаїл Мігель

@Ismael Мігель Не, цей код C все-таки був досить дурним
ace_HongKongIndependence

9

JavaScript

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

Виконання:

  • Chrome: результати в"Cat is fine"
  • Firefox: результати в"Cat is dead"

Пояснення:

15.5.4.9 String.prototype.localeCompare (що)

Дві рядки порівнюються у визначеному варіантом виконанні

Цитуючи Глена Рендерса-Перхсона, ймовірність не визначається програмою; це залежить від вибору браузера, який робить користувач.


Не відтворюється на FF 27. На якій версії ви тестуєте?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

-1: невизначена поведінка та визначена реалізацією поведінка абсолютно різні.
whitequark

2
@whitequark Ні, вони не є. Це визначена функція з невизначеним результатом. Ерго невизначена поведінка.
Джордж Рейт

1
@whitequark Я не бачу тут жодного C. Що стосується JavaScript, чи не має JavaScript визначеної поведінки, здається, вважається, що визначена реалізацією поведінка є прохідною.
Джордж Рейт

1
@whitequark ніхто більше не плутає. Слово - це слово, мені не потрібен комітет, який би сказав мені, що це означає.
Джордж Рейт

9
int foo() {}

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

Читання значення функції, яке повинно повернути значення, призводить до невизначеної поведінки. Тепер очевидно, [цитування потрібне], що "щоразу, коли ви досягаєте невизначеної поведінки, Бог вбиває кошеня". За допомогою цього робимо висновок:

  • Ймовірність, що ви досягнете невизначеної поведінки - 100%
  • Ймовірно, саме ваш кошеня вбив бога - 1/200 000 000 дивіться чому
  • Так що ймовірність становить 0,0000005%

Може бути легко подовжений петлею, щоб знищити всіх котів у світі.


5
Ваша ймовірність в 100 разів зависока (200 М кішок, а не 2 М).
угорен

Я маю в відсотках. :)
Петро

1
Це в відсотках, і все-таки це в 100 разів занадто багато.
угорен

Ви маєте рацію, я вже не можу читати номери.
Петро

Це неправильно. UB викликається лише в тому випадку, якщо абонент намагається використати повернене значення. В іншому випадку цілком законно і чітко визначено відхід від кінця функції з недійсним типом повернення.
Р ..

5

Java (Збір сміття)

Хоча код може викликати System.gc (), це не гарантує, що збирач сміття збиратиме всі невикористані об'єкти. Таким чином, для наступного коду непередбачувано, буде кішка вбита чи ні.

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

Ймовірність не може бути обчислена.

Зауважте, що є ще ймовірність, що кішка буде "оживлена", якщо в системному потоці GC після виходу із системи та перед System.exit (0) буде контекстний перемикач, але я вважав за краще не охоплювати його, щоб зробити концепцію простішою.


1
Це не добре. Цей код, як написано, майже завжди надрукує обидва. Краще було б додати System.out.close()після System.out.println("Cat is still alive.");рядка.
durron597

Наскільки я розумію, «майже завжди» відповідає аспекту непередбачуваності питання.
user3001267

5

Хтось подумав, що справді вбив (а) cat?

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

Ймовірність catвмирання

Для ймовірності ... Я думаю, нам потрібно розрізнити деякі випадки:

  1. Користувач Windows : Напевно, не вдасться його виконати. Шанс померти cats дуже низький, можна сміливо вважати рівним нулю. Якщо у нього встановлений Cygwin, він вважатиметься користувачем Unix.
  2. Користувач Unix, який працює без кореневих привілеїв : вбивство catне вдасться.
  3. Користувач Unix, який працює з привілеями root : Хоча кожен виклик вбиватиме cats лише з шансом 1/6, він, ймовірно, повторюватиме його, поки не відбудеться щось несподіване. Без втрати загальності я припускаю cat, що неодмінно помре.

Загальна ймовірність залежить від того, наскільки користувачі змішані, і важко визначити. Але можна з упевненістю сказати: Windows - безпечне місце для кошенят.

Тестування на дотримання правил

Жодна тварина не може завдати шкоди під час створення вашої відповіді.

Це не вбивало тварин, відповідь схвалюється Американською асоціацією гуманного зв’язку .

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

чітко доводить, що catце не тварина (до тих пір, fileпоки не знає жодного виду прихованого типу спадкування файлу).


5

С

Якщо ім'я вашої кішки занадто довге, воно вмирає. getsспричиняє смерть котів разом з іншими проблемами.

#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

Хаскелл

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

Тут ми застосовуємо unsafePerformIOдо дії, яка має помітні побічні ефекти . Це завжди невизначена поведінка, принаймні, це порядок ефектів. Таким чином, або програма спочатку зазнає краху при спробі оцінити undefined(що, як не дивно, це не визначена поведінка: вона ніколи не повинна дати значення, яке дозволило б програмі продовжувати щось інше), або насправді спричинить серйозний міжнародний побічні ефекти. У цьому випадку шанс виживання становить лише 0,001% .

Ймовірність вбити кішку таким чином: 49,9995%.


3

Чт

Оскільки питання дозволяє мові, яка не має визначеної поведінки, доки ефект схожий, я вибираю Чт за його недетермінізм у виборі того, яке правило виконувати, коли є більше 1 правила, яке можна застосувати до поточного держава.

Програма подається в контролер для мікрохвильової печі, всередині якої знаходиться моя кішка. Двері в мікрохвильову піч закриваються і підсилюються застібкою-блискавкою. Вихід програми визначатиме, почне мікрохвильова піч кота чи ні.

  • Якщо вихід 0, ми розпочнемо експеримент щодо впливу тривалої дії мікрохвильової печі на живого ссавця (який наразі недостатньо досліджений).
  • Якщо вихід 1, ми просто будемо задоволені тим, що кішка щойно втратила одне із своїх 9 життів і випустила його.

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

Ймовірність вбити кота залежить від реалізації перекладача, але скажімо, це 50%. Тоді ймовірність того, що кішка помре, становить 0,5 .



@Score_Under: Який твій погляд?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Питання задає не визначену поведінку, яка передбачає використання поведінки мови, яка буде компілюватися та працювати, але не має конкретизації того, що вона насправді повинна робити. Прив'язування речей Math.random()до прикладу - це не визначена поведінка, а лише непередбачувана поведінка.
Score_Under

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

1

Java

За словами спец, java.util.Date буде мати невизначену поведінку. Тож спробуйте свою удачу:

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 );
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.