2012-11-08 19 views
8

thể trùng lặp:
Aliasing `T*` with `char*` is allowed. Is it also allowed the other way around?Đây có phải là sử dụng std :: mảng undefined hành vi?

Tôi đang sử dụng một std::array của char s để giữ một giá trị kiểu nguyên thủy chưa biết, đó là dài không quá 10 byte, như vậy:

std::array<char, 10> val; 
*reinterpret_cast<double*>(val.data()) = 6.3; 
//blah blah blah... 
double stuff = *reinterpret_cast<double*>(val.data()); 

Tôi đã đọc rằng truyền qua lại qua char * không phải là u xác định, bởi vì trình biên dịch giả định char * có thể bí danh một giá trị của bất kỳ loại nào. Điều này vẫn làm việc khi giá trị được đặt trong (những gì tôi giả định là) một mảng của char s bên trong đối tượng? Lưu ý: Tôi biết rằng tôi có thể sử dụng một liên minh ở đây, nhưng điều đó sẽ dẫn đến một số lượng lớn mã soạn sẵn cho những gì tôi đang làm và tôi muốn tránh nó nếu cần thiết, do đó, câu hỏi này là cần thiết.

+0

Câu hỏi khác nhau, cùng một câu trả lời. – Dan

+0

Cùng một câu hỏi, các từ khác nhau. ; -] – ildjarn

Trả lời

13

Có, std::array< char, 10 > không đáp ứng các yêu cầu căn chỉnh của double để reinterpret_cast kích động UB.

Hãy thử std::aligned_storage để thay thế.

+0

Căn chỉnh! Tất nhiên đó là một cái gì đó thậm chí không xảy ra với tôi. Cảm ơn vì liên kết đó, đó chính xác là những gì tôi cần. – Dan

0

Nó không có vấn đề gì mảng được chứa trong.

Tiêu chuẩn thậm chí không xem xét những gì bao quanh một cái gì đó (nó là cơ bản), nhưng không hỗ trợ chuyển đổi sang/từ char chuỗi.

Để thực hiện việc này trực tiếp qua reinterpret_cast và bài tập, bạn cần có bộ đệm được căn chỉnh chính xác.

Cách khác là sử dụng memcpy, không quan tâm đến căn chỉnh.

Trên một vấn đề có liên quan, thường không phải là một ý tưởng hay để chuyển xuống cấp độ nhị phân. Ví dụ, một sự thay đổi phiên bản đơn giản của trình biên dịch có thể làm cho một tệp dữ liệu nhị phân được tuần tự hóa không thể truy cập được. Một trình điều khiển chính để làm điều này anyway là cân nhắc hiệu suất thô.

+0

Có hỗ trợ chuyển đổi một 'char *' tùy ý thành 'double *' không? Tôi nghĩ rằng việc chuyển đổi con trỏ có thể bị mất. Hãy xem xét một ABI với các con trỏ có kích thước khác nhau. – Potatoswatter

+0

Loại thay đổi trình biên dịch nào có thể khiến điều đó xảy ra? – Dan

+0

Một con trỏ 'char' có độ phân giải địa chỉ chi tiết như bất kỳ con trỏ nào, giống như với' void'. Việc chuyển đổi con trỏ có thể bị mất mát nếu bộ đệm không được căn chỉnh chính xác. Dù sao, việc sao chép dữ liệu có thể là * không hiệu quả *. –

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