2010-09-02 37 views
9

Tôi đã xem đoạn mã sau và được thông báo rằng có nghĩa là COL_8888_RED là "độc lập cuối cùng". Tại sao? Điều gì làm cho người cuối này độc lập? (Tôi đã hỏi những coder gốc nhưng họ không nhận lại với tôi ... quái gì có lẽ họ cũng không biết.)Điều gì làm cho mã này "độc lập cuối cùng"?

union _colours { 
    uint8 c[3][4]; 
    uint32 alignment; 
}; 

static const union _colours col_8888 = { 
     { /* B  G  R  A in memory  */ 
       { 0x00, 0x00, 0xFF, 0xFF, }, /* red */ 
       { 0x00, 0xFF, 0x00, 0xFF, }, /* green */ 
       { 0xFF, 0x00, 0x00, 0xFF, }, /* blue */ 
     } 
}; 

#define COL_8888_RED *((uint32 *)&col_8888.c[0]) 
+0

Điều gì có thể là độc lập cuối cùng không an toàn, xem xét một số phần cứng khác có thể chọn ARGB, BGRA, RGBA, v.v ... –

+0

@ dash-tom-bang, thực sự các loại màn hình khác sẽ yêu cầu màu đỏ, màu xanh lá cây và màu xanh được xác định trong các đơn hàng byte khác nhau. Và trong trường hợp này, liên minh 'col_8888' xác định màu đỏ, xanh lá cây và xanh lam cho một loại màn hình cụ thể, và do đó định nghĩa một thứ tự byte cụ thể - nó đang được sử dụng * chỉ * để ghi vào kiểu hiển thị đó. Các loại hiển thị khác sẽ yêu cầu các định nghĩa khác nhau về màu đỏ, xanh lục và xanh lam. – BeeBand

Trả lời

11

Mã này không phải là "endian độc lập" trong một cảm giác rằng các nền tảng có tính xác thực khác nhau sẽ cung cấp cho bạn các giá trị khác nhau được xem qua COL_8888_RED. Nói cách khác, trong sự hiểu biết truyền thống về sự phụ thuộc cuối cùng, đoạn mã này phụ thuộc vào endian như nó từng nhận được.

Một câu hỏi khác là nơi mà COL_8888_RED được cho là được sử dụng. Có lẽ nó được dự định sẽ được chuyển đến một số API, mà bản thân nó phụ thuộc vào người cuối cùng theo cùng một cách đến mức phụ thuộc cuối cùng của API hủy bỏ sự phụ thuộc cuối cùng của COL_8888_RED. Trong trường hợp đó, mọi thứ sẽ hoạt động "như dự định", tức là riêng về cuối kỳ. (Ví dụ, nếu API nhận giá trị màu như uint32 và sau đó tách nó thành các thành phần ARGB bằng cách sử dụng sự kết hợp tương tự, nó sẽ nhận được đúng giá trị ARGB gốc bất kể endian.)

Nhưng tuy nhiên, để nói rằng giá trị của COL_8888_RED bởi chính nó là độc lập cuối cùng là hoàn toàn không chính xác.

+1

@Andrey, liệu thuật ngữ tốt hơn có phải là "thuyết bất khả tri cuối cùng" không? – BeeBand

+0

@BeeBand, sau đó chúng tôi thấy câu hỏi "Tại sao mã này là bất khả tri". Cùng một mức độ để tìm ra nó sẽ đi vào bất kỳ thuật ngữ khác được sử dụng. – maxwellb

+0

@Andrey, 'COL_8888_RED' sẽ được ghi trực tiếp vào phần tử trong một mảng' uint32'. – BeeBand

2

Tôi giả sử rằng COL_8888_RED, dưới dạng macro, sẽ luôn là uint32, miễn là macro COL_8888_RED luôn được sử dụng, mảng byte nguồn {0x00,0x00,0xFF, 0xFF} sẽ luôn dịch thành những gì lập trình viên muốn có nghĩa là RED.

Định nghĩa, sau đó, có nghĩa là bạn có thể viết cùng một mã nguồn trên một máy cuối lớn hoặc máy cuối nhỏ, và chuyển từ một mảng rời rạc sang màu logic.

CHỈNH SỬA: tại sao sau đó, không sử dụng kiểu liệt kê hoặc hằng số như "1"?

Có lẽ, các nhà phát triển API gốc muốn để có thể trỏ đến một vị trí của {0x00,0x00,0xFF, 0xFF} trong bộ nhớ, do đó mã như sau có thể được viết:

uint8 *p = malloc(sizeof(uint8)*4); 

fread(p, sizeof(uint8), 4, inBuff); 

if(*((uint32 *)p) == COL_8888_RED) 
{ 
    printf("I read red!\n"); 
} 
+0

FWIW, quá trình truyền tải như thế này không phù hợp với quy tắc bí danh nghiêm ngặt, điều này thực sự có thể gây ra sự cố, đặc biệt khi bật tối ưu hóa. –

3

Mảng các byte là endianness độc lập trên hầu hết các kiến ​​trúc. Bằng cách gán cho nó như là một mảng byte, lập trình viên đảm bảo nội dung phù hợp cho dữ liệu. Các byte cũng có thể được truy cập riêng lẻ trên bất kỳ kiến ​​trúc nào. Nếu bộ mã hóa vừa tạo một mảng gồm 3 từ, thì tính cuối của máy sẽ đóng một vai trò trong việc xác định bố cục chính xác của các bit.

Các vấn đề liên quan