Trong Ngày xưa (trước ANSI), việc xác định trước các biểu tượng như unix
và vax
là một cách để cho phép mã phát hiện tại thời điểm biên dịch hệ thống mà nó đang được biên dịch. Không có tiêu chuẩn ngôn ngữ chính thức nào trước đó (ngoài tài liệu tham khảo ở mặt sau của phiên bản đầu tiên của K & R), và mã C của bất kỳ sự phức tạp nào thường là một mê cung phức tạp #ifdef
để cho phép có sự khác biệt giữa các hệ thống. Các định nghĩa macro này thường được thiết lập bởi chính trình biên dịch, không được định nghĩa trong tệp tiêu đề thư viện. Do không có quy tắc thực sự nào về việc sử dụng mã định danh nào cho việc triển khai và được dành riêng cho các lập trình viên, nên các nhà văn trình biên dịch cảm thấy thoải mái khi sử dụng các tên đơn giản như unix
và cho rằng các lập trình viên sẽ đơn giản tránh sử dụng các tên đó cho mục đích riêng của họ.
Tiêu chuẩn ANSI C năm 1989 đưa ra các quy tắc hạn chế những biểu tượng mà việc triển khai có thể xác định trước một cách hợp pháp. Một macro được xác định trước bởi trình biên dịch chỉ có thể có một tên bắt đầu bằng hai dấu gạch dưới hoặc với một dấu gạch dưới theo sau là một chữ cái viết hoa, để các lập trình viên tự do sử dụng các định danh không khớp với mẫu đó và không được sử dụng trong thư viện chuẩn.
Kết quả là, bất kỳ trình biên dịch nào xác định trước unix
hoặc linux
không tuân thủ, vì nó sẽ không biên dịch mã hợp pháp hoàn hảo sử dụng một cái gì đó như int linux = 5;
.
Khi nó xảy ra, gcc không tuân thủ theo mặc định - nhưng nó có thể được thực hiện để phù hợp (khá hợp lý) với các tùy chọn dòng lệnh bên phải:
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
Xem hướng dẫn sử dụng gcc để biết thêm chi tiết.
gcc sẽ loại bỏ các định nghĩa này trong các bản phát hành trong tương lai, vì vậy bạn không nên viết mã phụ thuộc vào chúng. Nếu chương trình của bạn cần biết liệu nó có được biên dịch cho mục tiêu Linux hay không thì nó có thể kiểm tra xem đã __linux__
được xác định chưa (giả sử bạn đang sử dụng gcc hoặc trình biên dịch tương thích với nó). Xem hướng dẫn tiền xử lý GNU C để biết thêm thông tin.
Một phần lớn không liên quan sang một bên: người chiến thắng "Best One liner" của Cuộc thi mã Cffatedated quốc tế năm 1987 , bởi David Korn (vâng, tác giả của Korn Shell) đã tận dụng lợi thế của unix
macro được xác định trước :
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Nó in "unix"
, nhưng vì những lý do hoàn toàn không liên quan gì đến chính tả của tên macro.