2012-05-01 38 views
11
#define typecheck(type,x) \ 
({  type __dummy; \ 
     typeof(x) __dummy2; \ 
     (void)(&__dummy == &__dummy2); \ 
     1; \ 
} 

tệp typecheck.h chứa các mã này. tôi biết mã này là kiểm tra xem x có cùng loại với tham số loại hay không. nhưng tôi không thể hiểu được mã vềvề typecheck trong hạt nhân linux

(void)(&__dummy == &__dummy2); 

tại sao cách này có thể giải quyết này? địa chỉ đầu tiên của hai biến có thể có ý nghĩa? cảm ơn câu trả lời của bạn. hoặc cho tôi biết tôi nên học một số điểm.

Trả lời

7

So sánh con trỏ với các loại không tương thích là một ràng buộc vi phạm và yêu cầu trình biên dịch đưa ra chẩn đoán. Xem 6.5.9 khai thác bình đẳng:

chế

Một trong những điều sau đây sẽ tổ chức:

  • cả hai toán hạng có kiểu số học;
  • cả hai toán hạng là con trỏ đến phiên bản đủ điều kiện hoặc không đủ tiêu chuẩn của các loại tương thích;
  • một toán hạng là một con trỏ đến một đối tượng hoặc loại không đầy đủ và một là một con trỏ đến một phiên bản đủ điều kiện hoặc không đủ tiêu chuẩn của khoảng trống; hoặc
  • một toán hạng là một con trỏ và một là hằng số con trỏ null.

và 5.1.1.3 Chẩn đoán:

Thực hiện tuân thủ phải tạo ít nhất một thông báo chẩn đoán (được xác định theo cách thực hiện) nếu đơn vị dịch hoặc đơn vị dịch tiền xử lý vi phạm bất kỳ quy tắc cú pháp hoặc ràng buộc nào, ngay cả khi hành vi cũng được chỉ định rõ ràng là không xác định hoặc được xác định thực hiện. Thông báo chẩn đoán không cần phải được sản xuất trong các trường hợp khác.

8

Điều này sử dụng hai phần mở rộng GCC — câu lệnh biểu hiện ({ ... })typeof().

  1. Dòng đầu tiên của việc mở rộng khai báo biến có tên là type.
  2. Dòng thứ hai của việc mở rộng khai báo biến có cùng loại với biến hoặc biểu thức x.
  3. Dòng thứ ba so sánh hai con trỏ, sẽ chỉ khớp nếu các loại của hai biến giả phù hợp, tạo ra cảnh báo con trỏ không khớp (hoặc lỗi nếu biên dịch với -Werror).
  4. Dòng cuối cùng (chứa số 1) là giá trị của biểu thức — tương đương với đúng.

Vì vậy, bạn nhận được cảnh báo/lỗi biên dịch nếu loại x không giống với loại được đặt tên.

Ví dụ mã:

#include <stdio.h> 

#define typecheck(type,x) \ 
({  type __dummy; \ 
     typeof(x) __dummy2; \ 
     (void)(&__dummy == &__dummy2); \ 
     1; \ 
}) 

int main(void) 
{ 
    int x; 
    if (typecheck(int, x)) 
     printf("int x OK\n"); 
    if (typecheck(double, x)) 
     printf("double x OK\n"); 
    return(0); 
} 

nhắn Compilation:

$ /usr/bin/gcc -O3 -g -std=gnu99 -Wall -Wextra xx.c -o xx 
xx.c: In function ‘main’: 
xx.c:15: warning: comparison of distinct pointer types lacks a cast 
$ 

Lưu ý rằng vì tôi không sử dụng -Werror, mã biên soạn 'OK'. Đầu ra là:

int x OK 
double x OK 
+0

char buffer_array [10]; char * buffer_point; typecheck (typeof (& buffer_array), buffer_point) cung cấp cho waring "so sánh các kiểu con trỏ riêng biệt thiếu một dàn diễn viên". loại & buffer_array mà không phải là char *? – DaVid

+1

Với 'char buffer_array [10];', kiểu '& buffer_array' là 'con trỏ tới mảng của' 'char'', hoặc' char (*) [10] '. Mảng không phải là con trỏ; chúng có liên quan chặt chẽ, nhưng chúng không giống nhau. –

+0

nhận được nó。 typeof (& buffer_array [0]) == typeof (buffer_point) – DaVid

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