Có cách nào để tôi có thể khám phá loại biến tự động trong C, hoặc thông qua một số cơ chế trong chính chương trình, hoặc - nhiều khả năng - thông qua quá trình biên dịch trước kịch bản sử dụng trình biên dịch đi đến điểm mà nó đã phân tích các biến và gán cho chúng các kiểu của chúng? Tôi đang tìm kiếm các đề xuất chung về điều này. Dưới đây là nền tảng về những gì tôi cần và lý do tại sao.Lấy loại biến trong mã C
Tôi muốn thay đổi ngữ nghĩa của điều khoản giảm OpenMP. Tại thời điểm này, có vẻ như đơn giản nhất là thay thế mệnh đề trong mã nguồn (thông qua một kịch bản lệnh) bằng một cuộc gọi đến một hàm, và sau đó tôi có thể định nghĩa hàm để thực hiện các ngữ nghĩa giảm mà tôi muốn. Ví dụ, kịch bản của tôi sẽ chuyển đổi này
#pragma omp parallel for reduction(+:x)
vào đây:
my_reduction(PLUS, &x, sizeof(x));
#pragma omp parallel for
ở đâu, trước đó, tôi có (nói)
enum reduction_op {PLUS, MINUS, TIMES, AND,
OR, BIT_AND, BIT_OR, BIT_XOR, /* ... */};
Và my_reduction
có chữ ký
void my_reduction(enum reduction_op op, void * var, size_t size);
Trong số các t khác hings, my_reduction
sẽ phải áp dụng hoạt động bổ sung cho biến giảm như lập trình ban đầu đã dự định. Nhưng chức năng của tôi không thể biết làm thế nào để làm điều này một cách chính xác. Đặc biệt, mặc dù nó biết loại hoạt động (PLUS
), vị trí của biến gốc (var
) và kích thước của loại biến, nó không biết chính loại của biến đó. Đặc biệt, nó không biết liệu var
có loại tích phân hay dấu phẩy động hay không. Từ POV cấp thấp, hoạt động bổ sung cho hai loại loại này hoàn toàn khác nhau.
Nếu chỉ nhà điều hành không chuẩn typeof
, GCC hỗ trợ, sẽ hoạt động theo cách sizeof hoạt động - trả về một số loại biến - tôi có thể giải quyết vấn đề này dễ dàng. Nhưng typeof không thực sự thích sizeof: nó chỉ có thể được sử dụng, rõ ràng, trong các khai báo giá trị l.
Bây giờ, trình biên dịch rõ ràng không biết loại x trước khi nó kết thúc việc tạo mã thực thi. Điều này khiến tôi tự hỏi liệu bằng cách nào đó tôi có thể tận dụng bộ phân tích cú pháp của GCC, chỉ để lấy kiểu của x
và chuyển nó vào kịch bản của tôi, và sau đó chạy GCC một lần nữa, tất cả các cách, để biên dịch mã nguồn thay đổi của tôi. Sau đó, nó sẽ đủ đơn giản để khai báo
enum var_type { INT8, UINT8, INT16, UINT16, /* ,..., */ FLOAT, DOUBLE};
void my_reduction(enum reduction_op op, void * var, enum var_type vtype);
Và my_reduction
có thể truyền một cách thích hợp trước khi dereferencing và áp dụng toán tử.
Như bạn có thể thấy, tôi đang cố gắng tạo ra một loại cơ chế "cử đi" trong C. Tại sao không chỉ sử dụng quá tải C++? Bởi vì dự án của tôi hạn chế tôi làm việc với mã nguồn kế thừa được viết bằng C. Tôi có thể thay đổi mã tự động bằng một tập lệnh, nhưng tôi không thể viết lại nó thành một ngôn ngữ khác.
Cảm ơn!
Cách xử lý sau mã nguồn của bạn bằng một số công cụ/tập lệnh? Ví dụ. phân tích cú pháp bằng tiếng kêu, tìm các loại, chèn/điều chỉnh mã loại cụ thể, biên dịch? –
Cảm ơn, Alex. Nghe có vẻ như nó đang đi đúng hướng. –
Tôi đọc ở đâu đó mà người dùng xác định giảm sẽ là một phần của tiêu chuẩn 3.1 hoặc 4.0. Hm 3.1 nói: 'giảm ({toán tử | intrinsic_procedure_name}: danh sách)' ..không cố gắng intrinsic_procedure_name. mặc dù nó chỉ giải quyết một phần vấn đề phát hiện kiểu của bạn. – Bort