2011-11-22 17 views
5
#define HTON_I32(x) htonl(x) 
inline float __HTON_F32(float x) 
{ 
    int i = HTON_I32(*((int *)(&x))); 
    return (*((float *)(&i))); 
} 

Làm thế nào để giải quyết cảnh báo dereferencing type-punned pointer will break strict-aliasing rules trong đoạn code trênLàm thế nào để giải quyết cảnh báo: dereferencing type-punned con trỏ sẽ phá vỡ quy tắc nghiêm ngặt-aliasing

+0

Bạn có thể biên dịch với -fno-nghiêm ngặt cờ đánh dấu trên. Điều này sẽ loại bỏ cảnh báo về các vấn đề bí danh nghiêm ngặt –

+0

@TonyTheLion: điều đó không giải quyết được sự cố, nó ẩn nó và ẩn các vấn đề tiềm ẩn khác trong mã. Không phải là một ý tưởng tốt. – Mat

+0

@ Không, điều này giải quyết được vấn đề với chi phí tối ưu hóa. –

Trả lời

9

Loại bỏ các loại-punning, và thay thế bằng một cái gì đó isn' t mong manh khi đối mặt với răng cưa:

#include <string.h> 

inline float __HTON_F32(float x) { 
    int i; 
    memcpy(&i, &x, sizeof x); 
    i = HTON_I32(i); 
    memcpy(&x, &i, sizeof x); 
    return x; 
} 

trình biên dịch tối ưu hóa hợp lý sẽ làm giảm memcpy cuộc gọi, và tạo ra tương đương (đôi khi tốt hơn) mã với những gì bạn nhận được từ loại-punning.

Một giải pháp phổ biến khác mà bạn sẽ thấy liên quan đến công đoàn. Tất cả các giải pháp này giả định rằng sizeof(int) == sizeof(float). Bạn có thể muốn thêm một khẳng định cho hiệu ứng đó.

1

Bạn có thể sử dụng các công đoàn cho loại-punning, mà sẽ chăm sóc của các vấn đề liên kết và răng cưa có thể (C99: TC3 đề cập rõ ràng rằng đây là thực sự hợp pháp):

#include <stdint.h> 

inline float __HTON_F32(float x) { 
    union { float as_float; int32_t as_int; } value = { x }; 
    value.as_int = HTON_I32(value.as_int); 
    return value.as_float; 
} 
+1

Đối với bất kỳ ai muốn tham chiếu TC3, điều này nằm trong §6.5.2.3, chú thích 82 –

+0

. ..và chú thích chân trang 95 của cùng một phần của bản dự thảo C1x tháng 4;) – Christoph

+0

chính xác điều này làm gì. ? value.as_int = HTON_I32 (value.as_int); – Sudhakar

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