Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

exit(), abort() และ assert() ใน C/C++: ความแตกต่างและการใช้งาน

ทั้งสามฟังก์ชันใช้สำหรับจบโปรแกรมแต่มีพฤติกรรมและจุดประสงค์ต่างกัน

exit() - Normal Termination

จบโปรแกรมอย่างปกติ พร้อม Cleanup ครบถ้วน

พฤติกรรม

  • เรียก atexit() Handlers (LIFO)
  • Flush I/O Buffers
  • ปิด Open Streams/Files
  • เรียก Destructors ของ Static/Thread-local Objects (C++)
  • คืน Status ให้ OS

ไวยากรณ์

#include <stdlib.h>
void exit(int status);

ตัวอย่าง

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

int main() {
    int x = 10;
    printf("The value of x : %d\n", x);
    exit(0);  // Exit Code 0 = Success
    printf("This won't print");
    return 0;
}

abort() - Abnormal Termination

จบโปรแกรม ทันทีและผิดปกติ ไม่ทำ Cleanup ใดๆ มักสร้าง Core Dump

พฤติกรรม

  • ไม่เรียก atexit() Handlers
  • ไม่ Flush Buffers
  • ไม่เรียก Destructors
  • สร้าง Signal SIGABRT (อาจถูก Catch ได้)
  • สร้าง Core Dump (ถ้าระบบอนุญาต)

ไวยากรณ์

#include <stdlib.h>
void abort(void);

ตัวอย่าง

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

int main() {
    int a = 15;
    printf("The value of a : %d\n", a);
    abort();  // จบแบบผิดปกติ
    printf("This won't print");
    return 0;
}

ผลลัพธ์

The value of a : 15
Aborted (core dumped)

assert() - Debug Assertion

ตรวจสอบเงื่อนไข (Condition) ในขณะ Debug ถ้าเป็นเท็จ จะเรียก abort()

พฤติกรรม

  • ถ้า Expression เป็น True: ไม่ทำอะไร (No-op)
  • ถ้า Expression เป็น False: พิมพ์ Error Message แล้ว abort()
  • ถ้า Define NDEBUG ก่อน Include <assert.h>: ถูก Disable ทั้งหมด (Zero Overhead)

ไวยากรณ์

#include <assert.h>
void assert(int expression);

ตัวอย่าง

#include <stdio.h>
#include <assert.h>

int main() {
    int a = 15;
    printf("The value of a : %d\n", a);
    assert(a != 15);  // False -> Abort
    printf("This won't print");
    return 0;
}

ผลลัพธ์

The value of a : 15
Assertion failed: a != 15, file main.c, line 9
Aborted (core dumped)

ตารางเปรียบเทียบ

คุณสมบัติexit()abort()assert()
Termination TypeNormalAbnormalAbnormal (ถ้า Fail)
Cleanup (atexit, destructors)✓ ใช่✗ ไม่✗ ไม่ (เรียก abort)
Core Dump✗ ไม่✓ ใช่ (ปกติ)✓ ใช่ (ผ่าน abort)
Return Status to OS✓ ใช่✗ (Signal)✗ (Signal)
Use CaseNormal ExitCritical ErrorDebug Checks
Production Code✓ ใช้ได้✗ หลีกเลี่ยง✗ Disabled by NDEBUG

เมื่อไหร่ควรใช้แต่ละตัว

exit()

  • จบโปรแกรมปกติจากฟังก์ชันที่ไม่ใช่ main()
  • Error Handling ที่ต้อง Cleanup

abort()

  • Critical Errors ที่ไม่สามารถ Recover ได้ (Corrupted State)
  • Security Violations
  • หลีกเลี่ยงในโค้ดปกติ - ใช้ Exception (C++) หรือ Error Codes แทน

assert()

  • ตรวจสอบ Preconditions/Postconditions/Invariants ใน Development
  • Document Assumptions ในโค้ด
  • ไม่ใช่ Error Handling สำหรับ Runtime Errors (User Input, File I/O, Network)

Best Practice: Assert vs Error Handling

// ดี: Assert สำหรับ Programming Errors (Bugs)
void setAge(int age) {
    assert(age >= 0 && age <= 150);  // Bug ถ้า violate
    this->age = age;
}

// ไม่ดี: Assert สำหรับ Runtime Errors
FILE *fp = fopen("config.txt", "r");
assert(fp != NULL);  // ผิด! File ไม่มีเป็น Runtime Error ไม่ใช่ Bug

// ถูกต้อง: Error Handling สำหรับ Runtime
FILE *fp = fopen("config.txt", "r");
if (fp == NULL) {
    fprintf(stderr, "Cannot open config.txt\n");
    return ERROR_CODE;
}