2011-10-17 32 views
5

Nếu tôi có một cấu trúc như thế này:struct bố trí các thành viên nhớ

struct S { 
    ANY_TYPE a; 
    ANY_TYPE b; 
    ANY_TYPE c; 
} s; 

Tôi có thể an toàn cho rằng các giả định sau sẽ luôn luôn đúng trên tất cả các nền tảng?

((char *)&s.a) < ((char *)&s.c) 
((char *)&s.a + sizeof(s.a) + sizeof(s.b)) <= ((char *)&s.c) 

Trong C++?

+0

@VJo: Bạn có thể giải thích như thế nào không? –

+0

Ví dụ về ANY_TYPE nơi nó không giữ là gì? –

+0

Tại sao bạn muốn? Điểm của các cấu trúc là để loại bỏ kiểu đấu tranh này. – Beta

Trả lời

3

Có, trong C ít nhất. Trình biên dịch là miễn phí để chèn padding sau khi bất kỳ thành viên cấu trúc nhưng nó không phải sắp xếp lại các thành viên.

Nó cũng không được chèn đệm trước thành viên đầu tiên.

Từ C99, 6.7.2.1:

13/ Trong vòng một đối tượng cấu trúc, các thành viên phi bit trường và các đơn vị trong đó cắn-lĩnh vực cư trú có địa chỉ làm tăng theo thứ tự mà họ được khai báo. Một con trỏ trỏ đến một đối tượng cấu trúc, được chuyển đổi phù hợp, trỏ tới thành viên ban đầu của nó (hoặc nếu thành viên đó là một trường bit, sau đó đến đơn vị mà nó cư trú) và ngược lại. Có thể có đệm không tên trong một đối tượng cấu trúc, nhưng không phải ở đầu của nó.

15/ Có thể có phần đệm chưa đặt tên ở cuối cấu trúc hoặc công đoàn.

+0

Re * Nó cũng không phải chèn padding trước thành viên đầu tiên. *: Điều đó sẽ làm cho hầu hết các trình biên dịch không tuân thủ. Thêm một vtable trước thành viên đầu tiên là một cách tiếp cận rất phổ biến để thực hiện đa hình. –

+5

@DavidHammen Trước hết, vtables là một chi tiết thực hiện của C++, chứ không phải C. Thứ hai, yêu cầu thành viên không có padding-before-first-member chỉ dành cho POD (Plain Old Data). Các lớp học có vtables không phải là POD và do đó được phép có a.o. một con trỏ vtable trước thành viên dữ liệu đầu tiên. – Sjoerd

1

Trong C++, bạn có thể chắc chắn rằng các giả định này sẽ giữ. Trong cấu trúc như thế này, trình biên dịch không được phép thay đổi thứ tự của các thành viên.

0

Có, theo mặc định trình biên dịch C++ không được phép di chuyển xung quanh các phần tử trong cấu trúc mà làm cho cả hai câu lệnh trivially đúng.

0
  1. Có (miễn là sizeof (ANY_TYPE) không phải 0. Một số trình biên dịch cho phép nó không chuẩn - xem Can sizeof return 0 (zero)). Bạn sẽ được an toàn với < = hoặc chỉ giả định một trình biên dịch chuẩn.

Và trong C++ quá.

So sánh con trỏ chỉ có ý nghĩa bên trong mảng và cấu trúc/lớp, nói chung không.

4

Điều này đúng với cấu trúc, nhưng thay đổi trong C++ ngay sau khi bạn giới thiệu các chỉ định truy cập. Trình biên dịch được phép sắp xếp lại toàn bộ các khối được giới hạn bởi các bộ định danh truy cập.

+0

Điều đó có thực sự đúng không?Tiêu chuẩn cho biết, các biến thành viên được khởi tạo theo thứ tự chúng được liệt kê trong lớp. Tôi giả định rằng thứ tự tương đối của họ không thể thay đổi nhờ điều đó. – Xeo

+2

@Xeo Xem (ví dụ) tại đây http://stackoverflow.com/questions/4883655/access-specifier-in-c/4883764#4883764 Thật không may câu trả lời này không có dấu ngoặc kép chuẩn. Tôi sẽ cố gắng cung cấp một số. Về khởi tạo: Khởi tạo độc lập với thứ tự bộ nhớ. – pmr

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