ใน Old Days (pre-ANSI) การกำหนดสัญลักษณ์ล่วงหน้าเช่นunix
และvax
เป็นวิธีการที่อนุญาตให้โค้ดตรวจจับได้ในเวลารวบรวมซึ่งระบบที่ถูกรวบรวมไว้ ในตอนนั้นไม่มีมาตรฐานภาษาทางการ (นอกเหนือจากเอกสารอ้างอิงที่อยู่ด้านหลังของรุ่นแรกของ K&R) และรหัส C ของความซับซ้อนใด ๆ โดยทั่วไปจะเป็นเขาวงกตที่ซับซ้อนของ#ifdef
s เพื่อให้เกิดความแตกต่างระหว่างระบบ นิยามแมโครเหล่านี้มักถูกตั้งค่าโดยคอมไพเลอร์เองโดยไม่ได้กำหนดไว้ในไฟล์ส่วนหัวของไลบรารี เนื่องจากไม่มีกฎที่แท้จริงเกี่ยวกับตัวระบุที่สามารถนำมาใช้โดยการดำเนินการและที่สงวนไว้สำหรับโปรแกรมเมอร์นักเขียนคอมไพเลอร์รู้สึกอิสระที่จะใช้ชื่อง่าย ๆ เช่นunix
และสันนิษฐานว่าโปรแกรมเมอร์จะหลีกเลี่ยงการใช้ชื่อเหล่านั้นเพื่อจุดประสงค์ของตนเอง
มาตรฐาน ANSI C ปี 1989 แนะนำกฎที่ จำกัด สัญลักษณ์ที่การใช้งานสามารถกำหนดไว้ล่วงหน้าตามกฎหมาย แมโครที่คอมไพเลอร์กำหนดไว้ล่วงหน้าสามารถมีชื่อขึ้นต้นด้วยเครื่องหมายขีดล่างสองอันหรือขีดล่างตามด้วยตัวอักษรตัวพิมพ์ใหญ่ปล่อยให้โปรแกรมเมอร์อิสระที่จะใช้ตัวระบุที่ไม่ตรงกับรูปแบบนั้นและไม่ได้ใช้ในไลบรารีมาตรฐาน
เป็นผลให้คอมไพเลอร์ใด ๆ ที่กำหนดไว้ล่วงหน้าunix
หรือจะไม่สอดคล้องเพราะมันจะล้มเหลวในการรวบรวมรหัสสมบูรณ์ตามกฎหมายที่ใช้สิ่งที่ต้องการlinux
int linux = 5;
เมื่อมันเกิดขึ้น gcc จะไม่สอดคล้องตามค่าเริ่มต้น - แต่มันสามารถทำเพื่อให้เข้ากันได้ดีพอสมควรด้วยตัวเลือกบรรทัดคำสั่งที่ถูกต้อง:
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
ดูคู่มือ gccสำหรับรายละเอียดเพิ่มเติม
gcc จะยกเลิกคำจำกัดความเหล่านี้ในรุ่นอนาคตดังนั้นคุณไม่ควรเขียนโค้ดที่ขึ้นอยู่กับพวกเขา หากโปรแกรมของคุณจำเป็นต้องรู้ว่ามันถูกรวบรวมเพื่อเป้าหมาย Linux หรือไม่ก็สามารถตรวจสอบได้ว่า__linux__
มีการกำหนดไว้ (สมมติว่าคุณใช้ gcc หรือคอมไพเลอร์ที่เข้ากันได้กับมัน) ดูคู่มือผู้ประมวลผลก่อน GNU Cสำหรับข้อมูลเพิ่มเติม
สิ่งที่ไม่เกี่ยวข้องส่วนใหญ่: ผู้ชนะรางวัล "Best One Liner" จากการประกวดรหัส C ระหว่างประเทศปี 2530 โดย David Korn (ใช่ผู้เขียน Korn Shell) ใช้ประโยชน์จากunix
มาโครที่กำหนดไว้ล่วงหน้า:
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
มันพิมพ์"unix"
แต่ด้วยเหตุผลที่ไม่มีอะไรเกี่ยวข้องกับการสะกดชื่อแมโคร