2016-09-12 20 views
6

Với một struct tổng hợp/lớp, trong đó mỗi biến thành viên là các kiểu dữ liệu giống nhau:Có hợp lệ để đúc con trỏ đến struct để con trỏ mảng

struct MatrixStack { 
    Matrix4x4 translation { ... }; 
    Matrix4x4 rotation { ... }; 
    Matrix4x4 projection { ... }; 
} matrixStack; 

Làm thế nào hợp lệ là nó bỏ nó vào một mảng của các thành viên của nó? ví dụ.

const Matrix4x4 *ptr = reinterpret_cast<const Matrix4x4*>(&matrixStack); 
assert(ptr == &matrixStack.translation); 
assert(ptr + 1 == &matrixStack.rotation); 
assert(ptr + 2 == &matrixStack.projection); 
auto squashed = std::accumulate(ptr, ptr + 3, identity(), multiply()); 

Tôi đang làm điều này vì trong hầu hết các trường hợp, tôi cần đặt tên truy cập thành viên để rõ ràng, trong một số trường hợp khác, tôi cần chuyển mảng vào một số API khác. Bằng cách sử dụng reinterpret_cast, tôi có thể tránh phân bổ.

+0

sự hiểu biết của tôi là sử dụng kết quả của một dàn diễn viên đó sẽ không biên dịch trừ nếu sử dụng reinterpret_cast là hầu như luôn luôn mạo hiểm hành vi không xác định. Trường hợp cụ thể này có khả năng hoạt động như dự định (trừ khi trình biên dịch của bạn làm rối loạn liên kết cấu trúc sao cho các thành viên Matrix4x4 không tiếp giáp hoàn toàn trong bộ nhớ), nhưng nó vẫn không được đảm bảo bởi tiêu chuẩn. – antred

+0

Nó có thể hoạt động, có thể không, phụ thuộc vào kích thước thực tế của Matrix4x4 và cài đặt căn chỉnh dữ liệu –

+0

Cấu trúc có thể có đệm trong khi [mảng không bao giờ có đệm] (https://stackoverflow.com/questions/1066681/can-c-arrays-contain- padding-in-between-elements). – sashoalm

Trả lời

3

Việc truyền không yêu cầu phải hoạt động theo tiêu chuẩn.

Tuy nhiên, bạn có thể làm cho mã của bạn an toàn bằng cách sử dụng tĩnh khẳng định rằng sẽ ngăn chặn nó biên dịch nếu các giả định bị vi phạm:

static_assert(sizeof(MatrixStack) == sizeof(Matrix4x4[3]), "Size mismatch."); 
static_assert(alignof(MatrixStack) == alignof(Matrix4x4[3]), "Alignment mismatch."); 
// ... 
const Matrix4x4* ptr = &matrixStack.translation; 
// or 
auto &array = reinterpret_cast<const Matrix4x4(&)[3]>(matrixStack.translation); 
+1

Bạn không có nghĩa là '==' ở giữa hai đối số 'sizeof' /' alignof'? –

+0

@AaronMcDaid Bạn đọc được suy nghĩ của tôi, đã sửa! –

+0

Và có thể thêm một kiểm tra mà 'offsetof (MatrixStack, dịch) == 0'. Yếu tố đầu tiên có luôn được bảo đảm là có bù không? Chúng tôi có thể kiểm tra xem hai thành viên còn lại có dự kiến ​​không. –

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