Di Hari Tua (sebelum ANSI), simbol yang telah ditentukan sebelumnya seperti unix
dan vax
merupakan cara untuk memungkinkan kode untuk mendeteksi pada waktu kompilasi sistem apa yang sedang dikompilasi. Tidak ada standar bahasa resmi pada waktu itu (di luar bahan referensi di bagian belakang edisi pertama K&R), dan kode C kompleksitas apa pun biasanya merupakan labirin rumit #ifdef
untuk memungkinkan perbedaan antar sistem. Definisi makro ini umumnya ditetapkan oleh kompiler itu sendiri, tidak didefinisikan dalam file header perpustakaan. Karena tidak ada aturan nyata tentang pengidentifikasi yang dapat digunakan oleh implementasi dan yang disediakan untuk programmer, penulis kompiler merasa bebas untuk menggunakan nama-nama sederhana seperti unix
dan berasumsi bahwa programmer hanya akan menghindari menggunakan nama-nama itu untuk tujuan mereka sendiri.
Standar ANSI C 1989 memperkenalkan aturan yang membatasi simbol apa yang bisa ditetapkan secara hukum oleh suatu implementasi. Makro yang telah ditentukan sebelumnya oleh kompiler hanya dapat memiliki nama yang dimulai dengan dua garis bawah, atau dengan garis bawah diikuti dengan huruf besar, membuat programmer bebas untuk menggunakan pengidentifikasi yang tidak cocok dengan pola itu dan tidak digunakan di perpustakaan standar.
Akibatnya, setiap kompiler yang menentukan unix
atau linux
tidak sesuai, karena akan gagal untuk mengkompilasi kode legal yang menggunakan sesuatu seperti int linux = 5;
.
Seperti yang terjadi, gcc tidak sesuai secara default - tetapi dapat dibuat untuk menyesuaikan (cukup baik) dengan opsi baris perintah yang benar:
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
Lihat manual gcc untuk lebih jelasnya.
gcc akan menghapus definisi ini dalam rilis mendatang, jadi Anda tidak harus menulis kode yang bergantung pada mereka. Jika program Anda perlu tahu apakah sedang dikompilasi untuk target Linux atau tidak, ia dapat memeriksa apakah __linux__
sudah ditentukan (dengan asumsi Anda menggunakan gcc atau kompiler yang kompatibel dengannya). Lihat manual preprosesor GNU C untuk informasi lebih lanjut.
Samping yang sebagian besar tidak relevan: pemenang "Best One Liner" dari Kontes Kode C Internasional 1987 Disusupkan , oleh David Korn (ya, penulis Korn Shell) mengambil keuntungan dari unix
makro yang telah ditentukan :
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Mencetak "unix"
, tetapi karena alasan yang sama sekali tidak ada hubungannya dengan ejaan nama makro.