2013-03-09 31 views
6

Vì vậy, tôi đang sử dụng thư viện C này trong ứng dụng C++ của tôi và một trong các hàm trả về khoảng trống *. Bây giờ tôi không phải là người sắc nét nhất với C thuần khiết, nhưng đã nghe nói rằng một khoảng trống * có thể được truyền tới khá nhiều loại * khác. Tôi cũng biết rằng tôi mong đợi một phao ở cuối một nơi nào đó từ chức năng này.void * nghĩa là nổi, cách truyền?

Vì vậy, tôi bỏ khoảng trống * vào phao * và bỏ qua dấu phẩy *, lỗi. darn !. Tôi gỡ lỗi mã và trong gdb để cho nó đánh giá (float)voidPtr và thấp và nhìn thấy giá trị là những gì tôi mong đợi và cần!

Nhưng chờ đợi, không thể giống nhau trong thời gian biên dịch. Nếu tôi viết float number = (float)voidPtr; nó không biên dịch, điều đó là dễ hiểu.

Vì vậy, bây giờ là câu hỏi, làm thế nào để tôi nổi ra khỏi khoảng trống này *?

EDIT: Nhờ H2CO3 điều này đã được giải quyết, nhưng tôi thấy rất nhiều câu trả lời và nhận xét xuất hiện và dissappering không tin rằng tôi có thể làm (float) voidPtr trong gdb. đây là ảnh chụp màn hình.

enter image description here

+2

Tất nhiên, một giải pháp tốt hơn không kết thúc trong một tình huống như thế này để bắt đầu. – delnan

+3

@delnan, vì vậy OP nên bỏ toàn bộ thư viện vì nó sử dụng con trỏ void? –

+1

@CoreyOgburn Không, tôi đang nói về một con trỏ không được hiểu là con trỏ trống. 'void *' là hoàn toàn tốt trong một số trường hợp, nhưng trong trường hợp của OP, một người nào đó hơi say. Có lẽ OP đang sử dụng thư viện sai. – delnan

Trả lời

12

Hãy thử sử dụng con trỏ:

void *theValueAsVoidPtr = // whatever 

float flt = *(float *)&theValueAsVoidPtr; 
+8

Lưu ý rằng điều này giả định rằng 'sizeof (float) == sizeof (void *)' có thể không đúng, và trong trường hợp đó, điều này gọi hành vi không xác định. –

+1

Tác phẩm này, tôi đã bỏ lỡ phần bổ sung &. Không chắc chắn những gì hoặc tại sao chính xác điều này xảy ra ngay bây giờ, nhưng nó hoạt động. cảm ơn. – xNidhogg

+1

@xNidhogg Giải thích: loại an toàn của con trỏ yếu hơn con trỏ không. Bạn không thể bỏ 'void *' thành 'float', nhưng bạn có thể bỏ' void ** 'thành' float * '. Bây giờ khi bạn làm điều đó, và dereference địa chỉ của biến 'theValueAsVoidPtr', sau đó bạn nhận được * nội dung * của biến đó, chỉ trong một kiểu khác - điều này được gọi là kiểu punning. Xem [dòng được đánh dấu bằng "hack bit điểm động nổi"] (http://en.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code). –

8

Nếu tôi hiểu đúng, thư viện của bạn được trả lại một giá trị float trong một biến có kiểu được khai báo là void *. Cách an toàn nhất để làm cho nó trở lại một lần nữa là với một union:

#include <assert.h> 
static_assert(sizeof(float) == sizeof(void *)); 

union extract_float { 
    float vf; 
    void * vp; 
}; 

float foo(...) 
{ 
    union extract_float ef; 
    ef.vp = problematic_library_call(...); 
    return ef.vf; 
} 

Không giống như các phương pháp trong câu trả lời được chấp nhận, điều này không gây ra hành vi không xác định.

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