Bahasa C tidak ditentukan oleh satu compiler, melainkan oleh dokumen standar internasional ISO/IEC 9899. Dokumen ini terus diperbarui oleh komite WG14 setiap beberapa tahun sekali. Pada Chapter ini kita akan menelusuri versi-versi standar C yang paling sering dijumpai, melihat fitur apa yang ditambahkan di setiap versi, dan mencoba beberapa fitur lewat contoh kode yang dikompilasi dengan flag -std yang berbeda.
Mengenal ISO/IEC 9899 #
ISO/IEC 9899 adalah standar resmi bahasa C yang dipelihara oleh komite teknis WG14 di bawah ISO. Versi-versi yang telah diterbitkan antara lain:
| Versi | Tahun | Nama umum | Sorotan fitur |
|---|---|---|---|
| C90 | 1990 | ANSI C / C89 | baseline standar formal pertama |
| C99 | 1999 | C99 | komentar //, deklarasi di tengah blok, _Bool, long long, VLAs |
| C11 | 2011 | C11 | _Static_assert, _Generic, atomic, thread <threads.h> |
| C17 | 2018 | C17 | perbaikan cacat, tidak ada fitur baru signifikan |
| C23 | 2024 | C23 | constexpr, bool/true/false keyword, atribut [[...]], auto |
Compiler GCC dan Clang menyediakan flag -std=cNN untuk memilih versi standar yang dipakai saat kompilasi. Flag ini sangat penting karena kode yang sah di C99 bisa jadi tidak sah di C89, dan sebaliknya beberapa fitur C23 belum tentu didukung compiler lama.
C99: Komentar Baris dan Deklarasi Fleksibel #
Standar C99 menambahkan dua fitur yang dipakai sehari-hari tanpa kita sadari: komentar // dan deklarasi variabel di tengah blok kode. Sebelum C99, semua deklarasi variabel harus berada di awal blok, dan komentar hanya boleh memakai pasangan /* ... */.
/* Komentar satu baris -- fitur C99 */
#include <stdio.h>
#include <stdbool.h>
int main(void) {
// Deklarasi variabel di tengah blok -- fitur C99
for (int i = 0; i < 3; i++) {
bool genap = (i % 2 == 0);
printf("i=%d, genap=%d\n", i, (int)genap);
}
return 0;
}Output yang Dihasilkan (dengan flag -std=c99):
i=0, genap=1
i=1, genap=0
i=2, genap=1Mari kita telaah baris-baris kode di atas:
- Baris 1 (
/* ... */): komentar gaya lama, valid di semua versi C. - Baris 5 (
int main(void)): tandavoiddi parameter didefinisikan sebagai “tidak ada argumen” sejak C99; kurung kosongmain()berarti “argumen tidak ditentukan”. - Baris 7 (
// ...): komentar satu baris gaya C++, baru sah mulai C99. - Baris 8 (
for (int i = 0; ...)): deklarasiidi dalamfor, fitur C99. - Baris 9 (
bool genap = ...;): tipe_Booldibungkus aliasboollewat header<stdbool.h>, diperkenalkan di C99.
Jika kode yang sama dikompilasi dengan flag -std=c89 -pedantic, GCC akan menolak komentar // dan deklarasi variabel di dalam for. Pesan galat yang muncul akan menyebutkan kedua fitur tersebut tidak diizinkan pada mode C89.
C11: Static Assert dan Generic Selection #
C11 menambahkan beberapa fitur yang mempermudah pemrograman generik dan pemeriksaan statis. Dua yang paling berguna bagi pemula adalah _Static_assert dan _Generic. _Static_assert memeriksa kondisi pada saat kompilasi; bila kondisi bernilai 0, kompilasi gagal dengan pesan yang kita berikan. _Generic memungkinkan satu makro memilih ekspresi berdasarkan tipe argumen, semacam function overloading terbatas.
#include <stdio.h>
/* _Static_assert: cek kondisi saat kompilasi -- fitur C11 */
_Static_assert(sizeof(int) >= 2, "int harus minimal 2 byte");
#define tipe(X) _Generic((X), \
int: "int", \
long: "long", \
double: "double", \
default: "lain")
int main(void) {
int a = 5;
long b = 10L;
double c = 3.14;
printf("a -> %s\n", tipe(a));
printf("b -> %s\n", tipe(b));
printf("c -> %s\n", tipe(c));
return 0;
}Output yang Dihasilkan (dengan flag -std=c11):
a -> int
b -> long
c -> doubleMari kita telaah baris-baris kode di atas:
- Baris 4 (
_Static_assert(sizeof(int) >= 2, "...")): compiler mengevaluasisizeof(int) >= 2saat kompilasi; bila0, kompilasi gagal dengan pesan yang ditentukan. - Baris 6-10 (
#define tipe(X) _Generic(...)): makro yang memakai_Genericuntuk memilih string literal sesuai tipe argumen. - Baris 13-15 (
int a = 5; long b = 10L; double c = 3.14;): tiga variabel dengan tipe berbeda. - Baris 16-18 (
tipe(a),tipe(b),tipe(c)): makro diekspansi ke string yang sesuai dengan tipe setiap variabel.
C23: Konstekspresi dan Atribut #
C23 yang disetujui tahun 2024 membawa banyak fitur modern. Yang paling sering dipakai adalah keyword constexpr, atribut [[nodiscard]]/[[deprecated]]/[[noreturn]], serta bool, true, dan false yang kini menjadi keyword bawaan tanpa perlu header <stdbool.h>.
#include <stdio.h>
constexpr int MAX = 10;
[[nodiscard]] int hitung(void) {
return MAX * 2;
}
int main(void) {
bool aktif = true; /* C23: bool/true/false jadi keyword */
auto x = 5; /* C23: auto berarti tipe default int */
printf("MAX = %d\n", MAX);
printf("hitung() = %d\n", hitung());
printf("aktif = %d\n", (int)aktif);
printf("x = %d\n", x);
return 0;
}Output yang Dihasilkan (dengan flag -std=c23):
MAX = 10
hitung() = 20
aktif = 1
x = 5Mari kita telaah baris-baris kode di atas:
- Baris 3 (
constexpr int MAX = 10;):MAXmenjadi konstanta compile-time; nilainya bisa dipakai sebagai ukuran array atau labelcasepadaswitch. - Baris 5 (
[[nodiscard]] int hitung(void)): atribut[[nodiscard]]meminta compiler memberi peringatan bila pemanggil membuang hasil kembalian fungsi. - Baris 10 (
bool aktif = true;): tanpa#include <stdbool.h>karenabool,true, danfalsekini keyword bawaan. - Baris 11 (
auto x = 5;): di C23autoberarti tipe disimpulkan; di C lamaautoberarti storage class lokal (jarang dipakai).
Memilih Standar untuk Proyek Baru #
Untuk proyek C baru, beberapa pertimbangan praktis:
- C11 aman dipakai karena didukung semua compiler modern dan sudah mengandung
_Static_assert,_Generic, serta<threads.h>. - C17 pilihan konservatif untuk kode produksi karena hanya berisi perbaikan cacat dari C11.
- C23 cocok untuk proyek yang target kompilernya selalu modern (GCC 14+, Clang 18+).
Bab-bab selanjutnya dalam Course ini akan memakai flag -std=c11 karena keseimbangan antara dukungan compiler dan ketersediaan fitur modern.