2010-09-21 27 views
6

Tôi có chức năng mất dấu * dài và cần chuyển nó sang thư viện bên ngoài có int không dấu * và trên nền tảng không được gán int/long có cùng kích thước.Một diễn viên đang vi phạm quy tắc bí danh nghiêm ngặt

void UpdateVar(unsigned long* var) { 
    // this function will change the value at the address of var 
    ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable 
} 

Điều này tạo ra cảnh báo nói rằng vi phạm quy tắc bí danh nghiêm ngặt. Có công việc nào xung quanh không?

Cảm ơn bạn

Chỉnh sửa: Tôi xin lỗi vì không rõ ràng. Mã này là bản cập nhật nguyên tử để đi quanh thư viện để lưu trữ nó không phải là một tùy chọn. Tôi có thể thả xuống để lắp ráp nhưng tôi muốn làm điều này trong C + +.

+0

chỉ cho một đối tượng đơn lẻ hoặc một mảng dài/int? – sellibitze

+0

Đó là một cửa hàng nguyên tử cho một bộ nhớ 32 bit. – coderdave

Trả lời

8
void UpdateVar(unsigned long* var) { 
    unsigned int x = static_cast<unsigned int>(*var); 
    ExternalLibUpdateVar(&x); 
    *var = static_cast<unsigned long>(x); 
} 
+0

Làm cho 'static_cast' và tôi muốn bỏ phiếu. – sbi

+0

Xin lỗi; không chú ý đến thẻ C++ – dave

+0

Sự khác biệt thực sự giữa 'static_cast' và' reinterpret_cast' trong trường hợp này là gì? – identity

2

này nên làm việc:

void UpdateVar(unsigned long* var) { 
    // this function will change the value at the address of var 
    ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var)); 
} 
+0

nguy hiểm nếu sizeof (dài)! = Sizeof (int) – nos

+0

Ông nói trong bài gốc rằng họ được đảm bảo có cùng kích thước trên nền tảng của mình. Nhưng có, bạn là đúng. – identity

+1

+1. Dưới những điều kiện nhất định, điều này thực sự thích hợp theo ý kiến ​​của tôi. Nhưng nó thực sự phụ thuộc vào trường hợp và tôi cảm thấy thoải mái hơn với một số loại 'sizeof (int) == sizeof (long)' kiểm tra trong chương trình làm cho trình biên dịch thất bại trong trường hợp điều kiện không được đáp ứng - C++ 0x 'static_cast' của ai? :-) – sellibitze

0

Không có gì trong những nhiệm vụ C tiêu chuẩn mà intlong phải có cùng kích thước; hơn nữa, ngay cả khi chúng có cùng kích thước, không có gì trong Standard yêu cầu chúng có cùng một biểu diễn (trong số những thứ khác, chúng có thể có sự kết hợp không tương thích giữa bit đệm và biểu diễn bẫy, như vậy răng cưa giữa hai loại không thể phân phối mục đích hữu ích).

Tác giả của tiêu chuẩn không muốn ép buộc người triển khai nhắm mục tiêu nền tảng nơi bí danh giữa intlong sẽ không phục vụ mục đích nhận ra bí danh như vậy. Họ cũng không muốn viết các quy tắc có thể áp dụng cho một số nền tảng (những người mà bí danh sẽ phục vụ một mục đích) nhưng không phải những quy tắc khác (những nơi mà nó sẽ không). Thay vào đó, họ nghĩ rằng những người viết trình biên dịch chất lượng sẽ cố gắng nhận ra răng cưa trong trường hợp nó hữu ích.

Có thể sử dụng con trỏ tới một loại 32 bit để đọc và ghi các giá trị của loại 32 bit khác có cùng biểu diễn rõ ràng là hữu ích, đặc biệt nếu API được phân tách theo loại mong muốn. Nếu một số API phổ biến trên nền tảng sử dụng int* cho các giá trị 32 bit và các giá trị khác sử dụng long*, thì chất lượng thực hiện chung cho nền tảng đó phải cho phép truy cập dữ liệu bằng cách sử dụng con trỏ của nền tảng kia. Tuy nhiên, không may, các tác giả của một số trình biên dịch quan tâm đến việc xử lý một tập hợp các chương trình nhất định một cách nhanh chóng, hơn là xử lý một tập con lớn hơn các chương trình một cách hữu ích và không thể dựa vào đó để tạo mã hữu ích nếu cần trao đổi dữ liệu giữa các API sử dụng cùng một biểu diễn dữ liệu nhưng các loại được đặt tên khác nhau trừ khi một loại hoàn toàn vô hiệu hóa phân tích bí danh. Tất nhiên, nếu một là nhắm mục tiêu phương ngữ của C phù hợp cho mục đích chung sử dụng trên vi điều khiển, các vấn đề như vậy không quan trọng.

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