Yêu cầu hơi khác một chút: Tôi cần một thử nghiệm như thế này trong tập lệnh cấu hình chương trình xây dựng chương trình để xác định xem máy đích biên dịch là bit hay endian, mà không cần thực thi mã . Kịch bản phải gửi #define HAVE_LITTLE_ENDIAN 1
vào một config.h
tiêu đề, hoặc nếu không #define HAVE_LITTLE_ENDIAN 0
.
Máy đích biên dịch có thể khác với máy xây dựng, vì chúng tôi có thể biên dịch chéo, điều này cũng giải thích tại sao thử nghiệm không được thử chạy bất kỳ mã được biên dịch nào. Không có vấn đề gì khi có một chương trình C nhỏ với một printf
tuyên bố phun ra câu trả lời.
Một giải pháp có thể là đây. Chúng tôi tạo ra một tệp có tên conftest.c
này:
#define USPELL(C0, C1, C2, C3) \
((unsigned) C0 << 24 | \
(unsigned) C1 << 16 | \
(unsigned) C2 << 8 | (unsigned) C3)
unsigned x[6] = {
0,
USPELL('L', 'I', 'S', 'P'),
USPELL('U', 'N', 'I', 'X'),
USPELL('C', 'O', 'R', 'E'),
USPELL('D', 'W', 'I', 'M'),
0
};
Bây giờ, chúng tôi biên dịch điều này để conftest.o
sử dụng:
$ /path/to/cross-compiling/cc conftest.c -c
Sau đó, chúng tôi chạy:
$ strings conftest.o
PSILXINUEROCMIWD
Nếu chuỗi PSILXINUEROCMIWD
xảy ra, mục tiêu là endian nhỏ. Nếu chuỗi LISPUNIXCOREDWIM
xảy ra, nó là endian lớn. Nếu không có chuỗi nào xảy ra hoặc, thậm chí đáng kinh ngạc hơn, cả hai đều làm, thì thử nghiệm đã thất bại.
Cách tiếp cận này hoạt động vì các hằng số "bốncc" được tính toán trong chương trình có các giá trị độc lập với máy, biểu thị các số nguyên giống nhau bất kể tuổi thọ. Biểu diễn lưu trữ của chúng trong tệp đối tượng tuân theo độ bền của hệ thống đích và được hiển thị thông qua chế độ xem dựa trên ký tự bên dưới strings
.
Hai từ bảo vệ bằng không đảm bảo rằng chuỗi được cách ly. Điều đó không thực sự cần thiết, nhưng nó đảm bảo rằng chuỗi mà chúng ta đang tìm kiếm không được nhúng vào một số chuỗi khác, có nghĩa là nó strings
sẽ tự xuất nó trên một dòng.
PS USPELL
macro không ngoặc đơn cho các phần chèn thêm đối số vì nó được tạo ra cho mục đích cụ thể này, không phải để sử dụng lại.