Принципова відмінність C і Java полягає в тому, що якщо уникнути певних легко ідентифікованих особливостей Java (наприклад, у Unsafe
просторі імен), будь-які можливі дії, які можна спробувати, в тому числі "помилкові", матимуть обмежений діапазон можливих результатів . Хоча це обмежує те, що можна зробити на Java - принаймні, не використовуючи Unsafe
простір імен, це також дозволяє обмежити шкоду, яка може бути заподіяна помилковою програмою, або - що ще важливіше - програмою, яка б правильно обробляла дійсні файли, але особливо захищені від помилкових.
Традиційно компілятори C обробляли б багато дій у визначеному Стандартом режимі у «звичайних» випадках, обробляючи безліч кутових справ «у спосіб, характерний для навколишнього середовища». Якщо хтось використовував процесор, який би вийшов з ладу і загорівся, якщо сталося числове переповнення, і хотілося уникнути загоряння процесора, потрібно було б написати код, щоб уникнути числового переповнення. Якщо ж хтось користувався процесором, який би абсолютно щасливо скорочував значення у способі доповнення двох, не довелося б уникати переповнення у випадках, коли таке укорочення призведе до прийнятної поведінки.
Сучасний C робить все на крок далі: навіть якщо націлений на платформу, яка природно би визначала поведінку для чогось подібного до числового переповнення, коли Стандарт не пред'являє жодних вимог, переповнення в одній частині програми може вплинути на поведінку інших частин програми програма у довільному порядку, не пов'язана законами часу та причинності. Наприклад, розгляньте щось на кшталт:
uint32_t test(uint16_t x)
{
if (x < 50000) foo(x);
return x*x; // Note x will promote to "int" if that type is >16 bits.
}
"Сучасний" компілятор C, що надає щось подібне, може зробити висновок, що оскільки обчислення x * x переповнюється, якщо x більше 46340, він може виконувати виклик "foo" беззастережно. Зауважте, що навіть якщо програма буде аномально закінчуватися, якщо x знаходиться поза діапазоном, або функція повертає будь-яке значення в таких випадках, виклик foo () з поза діапазоном x може завдати шкоди набагато більше будь-яка з цих можливостей. Традиційний C не забезпечить жодних засобів безпеки за винятком того, що постачає програміст та базову платформу, але дозволить запобіжникам обмежити шкоду від несподіваних ситуацій. Сучасний C обійде будь-які засоби безпеки, які не на 100% ефективні, щоб тримати все під контролем.