Đối với nhiều câu hỏi, câu trả lời của câu hỏi này là tùy thuộc . Thay vì nói cái nào tốt hơn tôi đã đưa ra những ví dụ và mục tiêu mà cái này tốt hơn cái kia.
Cả tiền xử lý và hằng có những nơi sử dụng riêng phù hợp.
Trong trường hợp bộ xử lý trước, mã được loại bỏ trước thời gian biên dịch. Do đó, nó phù hợp nhất cho các tình huống mà mã dự kiến sẽ không được biên dịch . Điều này có thể ảnh hưởng đến cấu trúc mô-đun, các phụ thuộc và nó có thể cho phép chọn các phân đoạn mã tốt nhất cho các khía cạnh hiệu suất. Trong các trường hợp sau đây, người ta phải chia mã bằng cách chỉ sử dụng bộ tiền xử lý.
Mã đa nền tảng:
Ví dụ: khi mã được biên dịch dưới các nền tảng khác nhau, khi mã có sự phụ thuộc vào số phiên bản cụ thể của HĐH (hoặc thậm chí là phiên bản trình biên dịch - mặc dù điều này rất hiếm). Ví dụ, khi bạn đang làm việc với các bản sao mã cuối cùng nhỏ cuối cùng - chúng phải được tách biệt với các bộ tiền xử lý thay vì hằng số. Hoặc nếu bạn đang biên dịch mã cho Windows cũng như Linux và các cuộc gọi hệ thống nhất định rất khác nhau.
Các bản vá thử nghiệm:
Một trường hợp khác mà điều này được đưa ra là hợp lý là một số mã thử nghiệm có rủi ro hoặc một số mô-đun chính cần được bỏ qua sẽ có sự khác biệt đáng kể về liên kết hoặc hiệu suất. Lý do tại sao người ta muốn vô hiệu hóa mã thông qua bộ tiền xử lý thay vì ẩn dưới if () là vì chúng tôi có thể không chắc chắn về các lỗi được đưa ra bởi bộ thay đổi cụ thể này và chúng tôi đang chạy trong cơ sở thử nghiệm. Nếu thất bại, chúng ta không phải làm gì khác ngoài việc vô hiệu hóa mã đó trong sản xuất hơn là viết lại. Đôi khi nó là lý tưởng để sử dụng #if 0
để nhận xét toàn bộ mã.
Xử lý các phụ thuộc:
Một lý do khác mà bạn có thể muốn tạo Ví dụ: nếu bạn không muốn hỗ trợ hình ảnh JPEG, bạn có thể giúp thoát khỏi việc biên dịch mô-đun / sơ khai đó và cuối cùng thư viện sẽ không liên kết (tĩnh hoặc động) với điều đó mô-đun. Đôi khi các gói chạy ./configure
để xác định tính khả dụng của sự phụ thuộc đó và nếu không có thư viện, (hoặc người dùng không muốn bật) chức năng đó sẽ tự động bị tắt mà không liên kết với thư viện đó. Ở đây luôn có lợi nếu các chỉ thị này được tạo tự động.
Cấp phép:
Một ví dụ rất thú vị về chỉ thị tiền xử lý là ffmpeg . Nó có codec có khả năng vi phạm bằng sáng chế bằng cách sử dụng nó. Nếu bạn tải xuống nguồn và biên dịch để cài đặt, nó sẽ hỏi bạn nếu bạn muốn hoặc tránh xa những thứ đó. Giữ các mã ẩn dưới một số nếu điều kiện vẫn có thể đưa bạn ra tòa!
Mã sao chép-dán:
Aka macro. Đây không phải là một lời khuyên để sử dụng quá mức các macro - chỉ là các macro có cách mạnh mẽ hơn nhiều để áp dụng tương đương sao chép trong quá khứ . Nhưng sử dụng nó rất cẩn thận; và sử dụng nó nếu bạn biết những gì bạn đang làm. Hằng số tất nhiên, không thể làm điều này. Nhưng người ta cũng có thể sử dụng các inline
chức năng nếu điều đó dễ thực hiện.
Vậy khi nào bạn sử dụng hằng số?
Hầu như mọi nơi khác.
Luồng mã gọn gàng hơn:
Nói chung, khi bạn sử dụng các hằng, nó gần như không thể phân biệt được với các biến thông thường và do đó, nó là mã dễ đọc hơn. Nếu bạn viết thường trình là 75 dòng - có 3 hoặc 4 dòng sau mỗi 10 dòng với #ifdef là RẤT không thể đọc được . Có thể được cung cấp một hằng số chính được quản lý bởi #ifdef và sử dụng nó trong dòng chảy tự nhiên mọi nơi.
Mã thụt lề tốt: Tất cả các chỉ thị tiền xử lý, không bao giờ hoạt động tốt với mã được thụt lề tốt . Ngay cả khi trình biên dịch của bạn không cho phép thụt lề #def, bộ tiền xử lý Pre-ANSI C không cho phép khoảng trống giữa đầu dòng và ký tự "#"; "#" hàng đầu phải luôn được đặt trong cột đầu tiên.
Cấu hình:
Một lý do khác khiến các hằng số / hoặc biến có ý nghĩa là chúng có thể dễ dàng phát triển từ việc được liên kết với toàn cầu hoặc trong tương lai có thể được mở rộng để được lấy từ các tệp cấu hình.
Một điều cuối cùng:
Không bao giờ sử dụng các chỉ thị tiền xử lý #ifdef
để #endif
vượt qua phạm vi hoặc { ... }
. tức là bắt đầu #ifdef
hoặc kết thúc #endif
ở các mặt khác nhau của { ... }
. Điều này là vô cùng tồi tệ; nó có thể gây nhầm lẫn, đôi khi có thể nguy hiểm.
Tất nhiên, đây không phải là một danh sách đầy đủ, nhưng cho bạn thấy sự khác biệt rõ ràng, nơi sử dụng phương pháp nào thích hợp hơn. Nó không thực sự là cái nào tốt hơn , nó luôn luôn được sử dụng nhiều hơn trong bối cảnh cụ thể.