ความแตกต่างพื้นฐานระหว่าง C และ Java คือถ้าใครหลีกเลี่ยงคุณลักษณะบางอย่างที่สามารถระบุตัวได้ง่ายของ Java (เช่นที่อยู่ในUnsafe
namespace) ทุกการกระทำที่เป็นไปได้หนึ่งอาจพยายาม - รวมทั้ง "ผิดพลาด" - จะมีช่วงที่ จำกัด . แม้ว่าสิ่งนี้จะ จำกัด สิ่งที่สามารถทำได้ใน Java อย่างน้อยโดยไม่ต้องใช้Unsafe
namespace แต่ก็สามารถจำกัดความเสียหายที่อาจเกิดขึ้นจากโปรแกรมที่ผิดพลาดหรือที่สำคัญกว่านั้นคือโปรแกรมที่ประมวลผลอย่างถูกต้อง ไฟล์ที่ถูกต้อง แต่ไม่ได้รับการป้องกันโดยเฉพาะกับไฟล์ที่ผิดพลาด
ตามเนื้อผ้าคอมไพเลอร์ C จะประมวลผลการกระทำมากมายในรูปแบบมาตรฐานที่กำหนดในกรณี "ปกติ" ในขณะที่การประมวลผลหลายมุมกรณี "ในลักษณะลักษณะของสภาพแวดล้อม" หากมีใครใช้ซีพียูที่จะลัดวงจรและลุกไหม้หากมีตัวเลขล้นเกิดขึ้นและต้องการหลีกเลี่ยง CPU ที่ติดไฟจะต้องเขียนโค้ดเพื่อหลีกเลี่ยงการล้นของตัวเลข อย่างไรก็ตามหากมีใครใช้ซีพียูซึ่งจะตัดค่าอย่างสมบูรณ์แบบอย่างมีความสุขอย่างสมบูรณ์แบบในแบบของสองคนก็ไม่จำเป็นต้องหลีกเลี่ยงการล้นในกรณีที่การตัดเช่นนั้นจะส่งผลให้พฤติกรรมที่ยอมรับได้
Modern 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.
}
คอมไพเลอร์ "modern" C ที่ให้บางอย่างเช่นด้านบนอาจสรุปได้ว่าเนื่องจากการคำนวณของ x * x จะล้นถ้า x มากกว่า 46340 มันสามารถทำการเรียกไปที่ "foo" โดยไม่มีเงื่อนไข โปรดทราบว่าแม้ว่ามันจะเป็นที่ยอมรับได้ที่จะมีโปรแกรมยุติอย่างผิดปกติถ้า x อยู่นอกช่วงหรือฟังก์ชั่นคืนค่าใด ๆ ในกรณีเช่นนี้การเรียก foo () ด้วยการอยู่นอกขอบเขต x อาจทำให้เกิดความเสียหายเกินกว่า ความเป็นไปได้เหล่านั้นอย่างใดอย่างหนึ่ง ดั้งเดิม C จะไม่ให้อุปกรณ์ความปลอดภัยใด ๆ นอกเหนือจากที่โปรแกรมเมอร์และแพลตฟอร์มที่ให้มา แต่จะอนุญาตให้อุปกรณ์ความปลอดภัยเพื่อจำกัดความเสียหายจากสถานการณ์ที่ไม่คาดคิด Modern C จะหลีกเลี่ยงอุปกรณ์ความปลอดภัยที่ไม่มีประสิทธิภาพ 100% ในการควบคุมทุกสิ่ง