Saat kita mempelajari standard library C, kita tidak perlu menghafal setiap fungsi—yang penting adalah tahu cara membaca dokumentasi dengan benar. Tiga sumber dokumentasi utama: cppreference.com (online, lengkap, dan gratis), halaman manual Unix (man pages, offline di Linux/macOS), dan dokumentasi resmi GCC/Clang. Setiap sumber memiliki struktur yang konsisten: function signature, deskripsi perilaku, return value, daftar error, dan contoh kode. Pada chapter ini kita akan meninjau cara membaca ketiga sumber, dengan studi kasus fungsi strtok_r dan strtol untuk menunjukkan bagaimana dokumentasi membantu kita menulis kode yang benar.
Sumber 1: cppreference.com #
cppreference.com adalah referensi online paling lengkap untuk C standard library, dengan URL pola https://en.cppreference.com/w/c/<kategori>/<fungsi>. Misalnya, dokumentasi strtok berada di https://en.cppreference.com/w/c/string/byte/strtok. Setiap halaman cppreference memiliki struktur konsisten yang patut kita kenali:
- Signature: prototype lengkap dengan tipe parameter dan return type. Contoh:
char *strtok(char *str, const char *delim);. - Parameters: deskripsi setiap parameter—apa yang harus diisi, apakah boleh
NULL, konvensi ownership. - Return value: nilai yang dikembalikan, termasuk kasus error.
- Notes: catatan penting seperti thread safety, perilaku khusus, atau alternatif yang lebih aman.
- Example: contoh kode lengkap yang dapat dikompilasi.
- References: rujukan ke standard ISO/IEC 9899 §7 yang relevan.
- See also: fungsi-fungsi terkait yang mungkin lebih tepat untuk kasus kita.
Kunci membaca cppreference: perhatikan kotak Notes yang biasanya berisi peringatan penting. Sebagai contoh, dokumentasi strtok menyebutkan bahwa fungsi ini tidak reentrant (tidak aman untuk multi-thread) dan menyarankan strtok_r (POSIX) atau strtok_s (C11, opsional) sebagai alternatif.
#define _POSIX_C_SOURCE 200809L /* Aktifkan strtok_r dari POSIX */
#include <stdio.h>
#include <string.h>
/* Contoh: memahami dokumentasi fungsi strtok_r */
int main(void) {
char input[] = "apel, jeruk, mangga; pisang";
const char *delimiter = ", ;";
char *saveptr = NULL; /* state untuk strtok_r */
/* Iterasi pertama: dapatkan token pertama */
char *token = strtok_r(input, delimiter, &saveptr);
while (token != NULL) {
printf("Token: \"%s\"\n", token);
/* Iterasi berikutnya: input NULL = lanjutkan dari posisi sebelumnya */
token = strtok_r(NULL, delimiter, &saveptr);
}
/* Bandingkan dengan strtok yang tidak reentrant */
char input2[] = "satu dua tiga";
token = strtok(input2, " ");
while (token != NULL) {
printf("strtok: \"%s\"\n", token);
token = strtok(NULL, " ");
}
return 0;
}Output yang Dihasilkan:
Token: "apel"
Token: "jeruk"
Token: "mangga"
Token: "pisang"
strtok: "satu"
strtok: "dua"
strtok: "tiga"Mari kita telaah baris-baris kode di atas:
- Baris 1 (
#define _POSIX_C_SOURCE 200809L): feature test macro yang meminta header mengekspos fungsi POSIX sepertistrtok_r. Tanpa makro ini (atau dengan-std=c11murni),strtok_rtidak dideklarasikan dan kompilasi gagal. cppreference selalu mencatat feature test macro yang diperlukan di bagian Notes. - Baris 9 (
char *saveptr = NULL;): parameter ketigastrtok_rmenyimpan state antar pemanggilan—berbeda daristrtokyang menyimpan state di variabel statis internal. Inilah yang membuatstrtok_rreentrant—banyak thread bisa memakainya bersamaan. - Baris 12 (
strtok_r(input, delimiter, &saveptr)): pemanggilan pertama denganinputnon-NULL. Fungsi mencari token pertama, mengganti karakter delimiter pertama dengan'\0', dan mengembalikan pointer ke token. - Baris 15 (
strtok_r(NULL, delimiter, &saveptr)): pemanggilan berikutnya denganNULL—fungsi melanjutkan dari posisi tersimpan disaveptr. Pola ini diulang sampai return valueNULLmenandakan tidak ada token lagi. - Baris 20-25 (
strtok): versi non-reentrant. Sintaks lebih sederhana (tanpasaveptr), tetapi state internal global—tidak aman dipakai bersamaan dari multiple thread.
Sumber 2: Halaman Manual (man pages) #
Di sistem Unix-like, halaman manual bisa diakses lewat perintah man di terminal. Manual terbagi menjadi beberapa section berdasarkan topik:
- Section 1: perintah shell (
man 1 printf= perintahprintfdi shell, bukan fungsi C). - Section 2: system call kernel (
man 2 open,man 2 read). - Section 3: fungsi library C (
man 3 strlen,man 3 printf). - Section 7: konvensi dan overview (
man 7 signal,man 7 errno).
Bila sebuah nama ada di beberapa section (misalnya printf ada di section 1 dan 3), tentukan section secara eksplisit: man 3 printf. Struktur halaman manual yang sering kita temui: NAME (nama singkat), SYNOPSIS (signature), DESCRIPTION (penjelasan detail), RETURN VALUE, ERRORS (untuk system call), EXAMPLES, SEE ALSO, COLOPHON.
Halaman manual tersedia offline—berguna saat kita tidak punya akses internet. Bila man tidak terinstal, man page mentah masih bisa dibaca dengan zcat /usr/share/man/man3/strlen.3.gz | groff -man -Tutf8 | less. Beberapa distribusi Linux minimal (seperti Docker container) tidak menyertakan man secara default—instal dengan apt install manpages-dev (Debian/Ubuntu).
Sumber 3: Dokumentasi GCC dan Clang #
Dokumentasi compiler (GCC: gcc.gnu.org/onlinedocs, Clang: clang.llvm.org/docs) berbeda dari dokumentasi standard library. Fokus compiler docs adalah extension dan option kompilasi. Yang paling sering kita rujuk:
- Attribute syntax:
__attribute__((unused)),__attribute__((format(printf, 1, 2))),__attribute__((warn_unused_result)). - Built-in functions:
__builtin_expect,__builtin_popcount,__builtin_add_overflow. - Warning options:
-Wall,-Wextra,-Wformat-security,-Wconversion. - Optimization options:
-O0(debug),-O2(release),-Os(size).
Sebagai contoh, dokumentasi GCC menjelaskan __attribute__((format(printf, n, m))) yang memerintahkan compiler memvalidasi argumen fungsi seperti printf. Dengan attribute ini, bila kita salah menulis format specifier, compiler memberikan warning di compile-time—bukan saat program crash di runtime.
Studi Kasus: Membaca Dokumentasi strtol untuk Error Handling #
Mari rangkum dengan studi kasus: kita ingin mengkonversi string angka dari input pengguna dengan validasi penuh. Membaca cppreference untuk strtol, kita temukan tiga sumber error yang harus diperiksa:
errno == ERANGE— overflow (angka terlalu besar untuklong).endptr == input— tidak ada karakter angka sama sekali yang dikonversi.*endptr != '\0'— ada karakter sisa setelah angka valid (input tidak sepenuhnya angka).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Demonstrasi: membaca dokumentasi untuk error handling */
/* Sumber: https://en.cppreference.com/w/c/string/byte/strtol */
int main(void) {
const char *inputs[] = {
"123abc", /* valid + sisa */
"0x1F", /* heksadesimal - tapi base 10, jadi tidak diparse */
" -42", /* whitespace + negatif */
"999999999999999999999999", /* overflow */
"bukan_angka" /* tidak ada angka sama sekali */
};
size_t n = sizeof(inputs) / sizeof(inputs[0]);
for (size_t i = 0; i < n; i++) {
errno = 0;
char *endptr = NULL;
long val = strtol(inputs[i], &endptr, 10);
/* Diagnosis error: */
/* 1. errno == ERANGE -> overflow */
/* 2. endptr == input -> tidak ada konversi */
/* 3. *endptr != '\0' -> ada karakter sisa */
printf("Input: \"%s\"\n", inputs[i]);
printf(" Hasil: %ld", val);
if (errno == ERANGE) {
printf(" [OVERFLOW: %s]", strerror(errno));
}
if (endptr == inputs[i]) {
printf(" [TIDAK ADA ANGKA]");
} else if (*endptr != '\0') {
printf(" [sisa: \"%s\"]", endptr);
}
printf("\n\n");
}
return 0;
}Output yang Dihasilkan:
Input: "123abc"
Hasil: 123 [sisa: "abc"]
Input: "0x1F"
Hasil: 0 [sisa: "x1F"]
Input: " -42"
Hasil: -42
Input: "999999999999999999999999"
Hasil: 9223372036854775807 [OVERFLOW: Numerical result out of range]
Input: "bukan_angka"
Hasil: 0 [TIDAK ADA ANGKA]Mari kita telaah baris-baris kode di atas:
- Baris 19 (
errno = 0;): wajib me-reseterrnosebelum memanggilstrtol. Tanpa ini,errnobisa berisi nilai sisa dari kegagalan sebelumnya yang tidak ada hubungannya dengan pemanggilan saat ini. Dokumentasi cppreference secara eksplisit menyebut langkah ini. - Baris 20 (
char *endptr = NULL;): deklarasi pointer yang akan diisistrtoldengan alamat karakter pertama yang tidak ikut diparse. Bilaendptrsama denganinput(pointer awal), berarti tidak ada karakter angka valid sama sekali. - Baris 21 (
strtol(inputs[i], &endptr, 10);): parameter ketiga10menentukan basis numerik. Bila kita isi0,strtolauto-detect (0xprefix = hex,0prefix = octal, lainnya desimal). Untuk input"0x1F"dengan base10, hanya karakter'0'yang diparse—'x'bukan digit desimal, jadiendptrmenunjuk ke"x1F". - Baris 31 (
if (errno == ERANGE)): tes pertama—overflow. Hasil9223372036854775807adalahLONG_MAX, yang di-returnstrtolbila input terlalu besar untuklong. - Baris 35 (
if (endptr == inputs[i])): tes kedua—tidak ada konversi sama sekali. Input"bukan_angka"menyebabkanendptrtetap di awal string. - Baris 37 (
else if (*endptr != '\0')): tes ketiga—ada karakter sisa. Input"123abc"menghasilkan123dengan sisa"abc". Bila kita mengharapkan input pure angka, sisa berarti input tidak valid.
Dengan tiga tes ini, kita dapat membedakan lima kasus berbeda: konversi sukses penuh, sukses sebagian, overflow, tidak ada angka, dan input dengan sisa karakter. Tanpa membaca dokumentasi secara cermat, kita mungkin hanya memeriksa return value strtol—yang tidak bisa membedakan kasus "0" valid dari "bukan_angka" (keduanya mengembalikan 0).
Strategi Belajar Standard Library #
Beberapa tips praktis saat belajar standard library:
- Mulai dari daftar fungsi: cppreference punya halaman index per header—misalnya
https://en.cppreference.com/w/c/string/byte. Lihat semua fungsi yang tersedia, jangan hanya cari yang kita sudah tahu. - Baca contoh: bagian Example di setiap halaman biasanya sudah cukup untuk memahami penggunaan dasar. Coba kompilasi dan modifikasi.
- Perhatikan Notes: ini sumber gotcha dan praktik terbaik yang tidak selalu jelas dari signature fungsi.
- Lihat standard reference: cppreference menyebutkan bagian ISO/IEC 9899 yang relevan di bagian References. Bila kita perlu kepastian hukum (formal standard), bisa rujuk draft standard gratis di
https://www.open-std.org/jtc1/sc22/wg14/. - Cross-check dengan kompiler: GCC dan Clang kadang memberikan warning yang spesifik untuk fungsi tertentu. Bila warning muncul, baca dokumentasinya.