Table of Contents
Viết mã C xách tay là nền tảng của kỹ thuật phần mềm chuyên nghiệp, cho phép ứng dụng chạy qua các cấu trúc phần cứng khác nhau, hệ thống điều hành và biên dịch với ít hiệu quả hơn. khả năng bảo trì chi phí, mở rộng cơ sở người dùng, và cách bảo vệ tương lai để chống lại các nền tảng phát triển. bài báo này phân hủy các thực hành tốt nhất để đạt được sự dễ dàng thực sự, dựa trên tiêu chuẩn C và thập kỷ kinh nghiệm thực tế của thế giới người dùng.
Hiểu rõ sự khác biệt nền tảng
Trước khi áp dụng các kỹ thuật cổng, các nhà phát triển phải nhận ra loại biến thể tồn tại giữa các nền tảng. những khác biệt này bao gồm bốn loại: hành vi biên dịch, điều hành hệ thống APIs, kiến trúc phần cứng và hạn chế tài nguyên.
Các biến thế
Các biên dịch viên — từ GCC, Clang, và MSVC để thực hiện tiêu chuẩn C với mức độ khác nhau. Họ có thể khác nhau trong việc quản lý [FLT: 0], bố trí bề mặt nhỏ, bố trí cấu trúc, và ngữ pháp chính xác . Phần mở rộng ngôn ngữ (v. d. phần mở rộng GNU C, phần mở rộng [FL3], Microsoft [FL] cũng có thể tạo quan hệ phụ thuộc.
Sự khác biệt về hệ thống điều hành
Hệ thống giống như PSIX (Linux, macOS, BSD) chia sẻ nhiều hệ thống API, nhưng Windows phơi bày một tập tin gọi hệ thống khác cơ bản. Tập tin I/O, luồng, kết nối, tín hiệu và tiến trình điều khiển thường cần thiết hoặc có điều kiện hợp nhất hoặc một lớp trừu tượng hoá. Ngay cả trường hợp độ nhạy và đường dẫn phân cách tập tin (tiếng cắt). Cần thiết cẩn thận.
Kiến trúc phần cứng và sự tận tụy
Các bộ xử lý khác nhau kích cỡ chữ [32 bit vs. 64 bit), thứ tự byte (bbendian hay ít ix), yêu cầu thẳng đứng và đặt tính năng. Mã (FLT:4) là 32 bit hoặc một con trỏ khớp trong một sẽ không còn hiệu lực trên nhiều nền tảng. Tính năng cuối cùng trở nên quan trọng khi việc sắp xếp dữ liệu nối tiếp cho mạng hay lưu trữ.
Các con điều khiển tài nguyên
Hệ thống nhúng hoặc mục tiêu nhúng sâu có thể thiếu hệ điều hành, có kích cỡ ngăn xếp/hap hạn chế, và cung cấp thực hiện với bộ thông số tối thiểu định dạng giới hạn. Mã số di động phải tránh giả định về khả năng có sẵn bộ nhớ và hỗ trợ thời gian chạy.
Các thực hành tốt nhất lõi cho mã C chuyển được
Nương cậy nơi những lời ca lành tiêu chuẩn
Thư viện C (ISO/IEC 9899) cung cấp một đường thẳng cơ bản mà mỗi trình biên dịch phải cung cấp. Hàm như , , , , và hành động giống hệt nhau. Tránh trình biên dịch đặc trưng tương đương , [PHST:12], nếu không được bảo vệ bởi [FL:12]. Đối với các hoạt động toán học, [L: 13] hơn các thư viện đa số véc - tơ.
Dùng kiểu nguyên tố cố định
Đầu trang định nghĩa kiểu , , đảm bảo kích cỡ chính xác. Luôn luôn dùng chúng khi phạm vi các giá trị — chẳng hạn, khi xác định bộ đệm hay bộ nhớ phần cứng. Tương tự, hãy dùng định dạng [[FL:18] [[FL: 17), [FL:19], [FL: 20] để in cổng này.
#include <stdint.h>
#include <inttypes.h>
int32_t val = -100;
printf("Value: %" PRId32 "\n", val);
Tránh những cách suy nghĩ cơ bản
Đừng bao giờ cho rằng là 32 bit, là 64 bit, hoặc được ký tên. Hãy dùng và hằng số (], [FLT: 27, [FL:28] để phân tích các tính chất vào thời gian soạn thảo. Đối với [FL:29], hãy dùng [FL:29] hoặc [FL:30] nếu bạn phải lưu trữ chúng như số nguyên.
Giải quyết tận gốc rễ
Khi trao đổi dữ liệu nhị phân [công việc làm, tập tin hoặc chia sẻ], luôn luôn chuyển đổi sang thứ tự byte được biết đến — thứ tự mạng thông thường (bLTED). Các chức năng PSIDEEE. Các chức năng PIST , , , , sẵn sàng rộng rãi; đối với hệ thống không dùng [FLSISSISSX], cung cấp khả năng thực hiện [FT:35] và chạy thời gian.
Các thao tác hệ thống tập tin trừu tượng
Đường dẫn tập tin khác nhau trên Unix, . Dùng vĩ mô hoặc chức năng tiện ích nhỏ để làm cho đường dẫn bình thường. Đối với thư mục, việc lặp lại thư mục ; trên Windows bạn có thể kết thúc [FL:39] đằng sau giao diện đó. Tránh đường dẫn tuyệt đối khó.
Thu nhỏ những hành vi không xác định và không khoan nhượng
Tiêu chuẩn C chỉ nhiều hoạt động như là chưa xác định hoặc thực hiện. Thí dụ gồm các số nguyên đã ký, dịch sang nhiều chiều rộng của loại, và đánh giá . Dùng bộ phân tích tĩnh như [FLT: 0] để bắt [FLT: 0] kiểm tra [FLT: 1] hoặc [FL:]lang [FLT] [FLT: TL: 3] để bắt những mẫu như thế, và viết những mã đó là theo đúng.
Name
Sự tính toán điều kiện là cần thiết cho các mã đặc trưng riêng của nền tảng, nhưng việc lạm dụng có thể tạo ra một mớ hỗn độn. Hãy dùng vĩ mô được biết trước: , , , , và biên dịch như . Luôn luôn tài liệu [FL:46] và giữ cho các phần riêng biệt của hệ thống.
#ifdef _WIN32
#include <windows.h>
#define SLEEP(ms) Sleep(ms)
#else
#include <unistd.h>
#define SLEEP(ms) usleep((ms)*1000)
#endif
Dùng lớp ngữ nghĩa cho cuộc gọi hệ thống
Để chỉ, ổ cắm, đồng hồ hẹn giờ, tạo các cuộn mỏng. Chẳng hạn, xác định một kiểu và chức năng vẽ các điểm ảnh thành các thư viện PISIX trên Unix và [FLT: 50] trên các cửa sổ. Cách tiếp cận tương tự cho thư viện động ( v. [FL:52]. Nhiều nguồn tài nguyên mở (v. d. [FL: 0p] [FL: 50] [FL] [FL], T] [FT], Bản dịch linh hoạt: 1] đã [FT] đã cung cấp [L].
Thử trên nhiều nền tảng sớm và thường xuyên
Các đường ống liên tục (CI) nên biên dịch và chạy dãy thử nghiệm trên Linux, macOS, Windows và bất kỳ mục tiêu nhúng nào. Hãy dùng bộ đếm chéo (v. d. QEMU) để bắt lỗi đặc trưng cấu trúc trước khi khởi chạy. Tự động thử nghiệm với các công cụ như [FLT: 0] [FL: 1] hoặc [FL: 2] [FT: 2] make [FL: 2] [FL: 2] Bộ điều khiển] khả năng bật/ tắt cổng.
Kỹ thuật công nghệ xử lý cổng cao cấp
Xây dựng cấu hình hệ thống bằng công cụ tạo hay chế độ tự động
Hệ thống xây dựng hiện đại có thể phát hiện các đặc điểm của hệ thống vào thời điểm cấu hình. Môđun của chế độ , và tạo ra một mà mã của bạn có thể bao gồm.
// Generated config.h
#define HAVE_STDINT_H 1
#define WORDS_BIGENDIAN 0
#define SIZEOF_LONG 8
Hội nghị chi tiết và nội dung
Khi chương trình yêu cầu chỉ dẫn đặc trưng cho nền tảng (v. d., SIMD, CPUID) gói chúng lại trong tập tin riêng biệt và chọn tập tin đúng trong khi xây dựng. Dùng trình biên dịch (như từ GCC/Clang/ICC/VS), thay vì trong việc lắp ráp dòng, vì nội dung dễ dàng hơn các trình biên dịch cùng cấu trúc.
Sắp xếp dữ liệu cấu hình mở rộng
Việc xếp chồng và sắp xếp mỗi khác. Dùng và cho GCC .
Tương thích với việc sử dụng tín hiệu
Hằng số tín hiệu (, và tín hiệu an toàn xử lý khác nhau. Tín hiệu xác định sau một hàm số thông thường để tránh ngạc nhiên.
Những cạm bẫy thật sự của thế giới và cách tránh chúng
Nương tựa vào mà không có sự sụp đổ
là chuẩn trên PISIX nhưng thiếu trên nhiều nền tảng nhúng và môi trường cũ hơn của Windows. Hãy dùng một thực hiện xách tay như [FLT: 0] phụ [FLT: 1] hoặc đóng gói tối thiểu dưới giấy phép tự do.
Giả sử là một nguyên có chữ ký
Tiêu chuẩn C chỉ nói là một loại có khả năng đại diện thời gian. Trên một số hệ thống, nó là một giá trị 32 bit chưa ký; trên một số khác nó là một số nguyên đã ký 64 bit. Không bao giờ thực hiện số học mà không kiểm tra tài sản của nó, hoặc dùng cho sự khác biệt.
Bỏ bê sự an toàn trong các cuộc gọi hệ thống
Hàm như , , và dùng bộ đệm tĩnh và không phải là chỉ an toàn. Hãy dùng những biến thể , , khi có thể, và cung cấp những bộ đệm rơi xuống trên nền không có bộ đệm.
Kết luận
Viết mã C xách tay là cả một kỷ luật lẫn một sự đầu tư. Bằng cách gắn bó chặt chẽ với tiêu chuẩn C, chọn các loại « i-mê-re-width » cố định, giao diện trừu tượng hóa hệ thống, và thử nghiệm trên nhiều nền tảng, các nhà phát triển có thể sản xuất phần mềm có khả năng chạy trong môi trường khác nhau từ siêu máy vi tính đến vi điều khiển vi mô. Các thực hành được liệt kê ở đây — kết hợp với cấu trúc hiện đại và phân tích trạng thái tĩnh — tạo một nền tảng bền vững cho sự phát triển qua hệ thống C. Hãy nhớ: khả năng xuất khẩu hiệu không phải là một mục tiêu sau khi suy nghĩ; nó là một thiết kế có thể đáp ứng được cuộc sống của một dự án xe đạp xe đạp.