Perpustakaan C tidak diatur errno
ke 0 karena alasan historis 1 . POSIX tidak lagi mengklaim perpustakaannya tidak akan mengubah nilai jika berhasil, dan halaman manual Linux baru untukerrno.h
mencerminkan hal ini:
File <errno.h>
header mendefinisikan variabel integer errno
, yang diatur oleh panggilan sistem dan beberapa fungsi perpustakaan jika terjadi kesalahan untuk menunjukkan apa yang salah. Nilainya signifikan hanya ketika nilai kembali panggilan menunjukkan kesalahan (yaitu, -1
dari sebagian besar panggilan sistem; -1
atau NULL
dari sebagian besar fungsi perpustakaan); fungsi yang berhasil adalah diizinkan untuk perubahan errno
.
The ANSI C Dasar Pemikiran menyatakan bahwa panitia merasa itu lebih praktis untuk mengadopsi dan standarisasi praktek yang ada menggunakan errno
.
Mesin pelaporan kesalahan yang berpusat pada pengaturan errno
umumnya dianggap dengan toleransi yang terbaik. Ini memerlukan `` penggabungan patologis '' antara fungsi-fungsi perpustakaan dan memanfaatkan sel memori statis yang dapat ditulisi, yang mengganggu pembangunan perpustakaan yang dapat dibagikan. Namun demikian, Komite lebih memilih untuk menstandarkan mesin yang ada, namun kekurangan ini, daripada menciptakan sesuatu yang lebih ambisius.
Hampir selalu ada cara untuk memeriksa kesalahan di luar memeriksa jika telah errno
diatur. Memeriksa apakah telah errno
ditetapkan tidak selalu dapat diandalkan, karena beberapa panggilan memerlukan panggilan API terpisah untuk mendapatkan alasan kesalahan. Misalnya, ferror()
digunakan untuk memeriksa kesalahan jika Anda mendapatkan hasil pendek dari fread()
atau fwrite()
.
Cukup menarik, contoh Anda menggunakan strtod()
adalah salah satu kasus di mana pengaturan errno
ke 0 sebelum panggilan diperlukan untuk mendeteksi dengan benar jika kesalahan telah terjadi. Semua fungsi strto*()
string ke angka memiliki persyaratan ini, karena nilai kembali yang valid dikembalikan bahkan dalam menghadapi kesalahan.
errno = 0;
char *endptr;
double x = strtod(str1, &endptr);
if (endptr == str1) {
/*...parse error */
} else if (errno == ERANGE) {
if (x == 0) {
/*...underflow */
} else if (x == HUGE_VAL) {
/*...positive overflow */
} else if (x == -HUGE_VAL) {
/*...negative overflow */
} else {
/*...unknown range error? */
}
}
Kode di atas didasarkan pada perilaku strtod()
seperti yang didokumentasikan di Linux . Standar C hanya menetapkan bahwa underflow tidak dapat mengembalikan nilai lebih besar dari positif terkecil double
, dan apakah atau tidak errno
diatur untuk ERANGE
implementasi didefinisikan 2 .
Sebenarnya ada tulisan penasehat sertifikat yang luas yang merekomendasikan selalu menetapkan errno
ke 0 sebelum panggilan perpustakaan dan memeriksa nilainya setelah panggilan menunjukkan kegagalan telah terjadi . Ini karena beberapa panggilan pustaka akan disetel errno
meskipun panggilan itu sendiri berhasil 3 .
Nilai errno
0 adalah pada startup program, tetapi tidak pernah diatur ke 0 oleh fungsi perpustakaan apa pun. Nilai errno
dapat diatur ke nol oleh panggilan fungsi perpustakaan apakah ada atau tidak kesalahan, asalkan penggunaan errno
tidak didokumentasikan dalam deskripsi fungsi dalam Standar C. Penting bagi suatu program untuk memeriksa konten errno
hanya setelah kesalahan dilaporkan. Lebih tepatnya, errno
bermakna hanya setelah fungsi pustaka yang menetapkan errno
kesalahan telah mengembalikan kode kesalahan.
1. Sebelumnya saya mengklaim itu untuk menghindari kesalahan dari panggilan sebelumnya. Saya tidak dapat menemukan bukti untuk mendukung klaim ini. Saya juga punya printf()
contoh palsu .
2. Terima kasih kepada @chux karena telah menunjukkan ini. Referensi adalah C.11 §7.22.1.3 ¶10.
3. Ditunjukkan oleh @KeithThompson dalam komentar.
errno
, Anda selalu dapat mengaturnya ke nol sendiri.