2016-04-24 18 views
15

Tôi có một công đoàn trong C như thế này:vị trí bộ nhớ của các nguyên tố trong C/C++ đoàn

union AUnion { 
    struct CharBuf { 
    char *buf; 
    size_t len; 
    } charbuf; 
    uint8_t num; 
    double fp_num; 
}; 

Câu hỏi của tôi là, tôi có thể đảm bảo rằng nếu được như sau:

union AUnion u; 

Sau đó, sau đây là đúng:

&u == &u.num 
&u == &u.fp_num 
&u == &u.charbuf 

Tức là tất cả chúng bắt đầu ở đầu phân đoạn bộ nhớ nơi u được lưu trữ.

Trong trường hợp chương trình C này được biên soạn với gcc version 5.3.0-std=c11 ở trên là đúng:

#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 

union AUnion { 
    struct CharBuf { 
     char *buf; 
     size_t len; 
    } charbuf; 
    uint8_t num; 
    double fp_num; 
}; 

int main(void) 
{ 
    union AUnion u; 
    printf("%d\n", ((void*)&u) == ((void*)&u.charbuf)); 
    printf("%d\n", ((void*)&u.charbuf) == ((void*)&u.num)); 
    printf("%d\n", ((void*)&u.num) == ((void*)&u.fp_num)); 
} 

Vì nó in:

1 
1 
1 

Biên dịch mã trên như C++ 11 với cùng một kết quả trình biên dịch trong cùng một đầu ra như biên dịch nó như C11.

Nhưng là hành vi tiêu chuẩn này? Nó không xác định? Tôi có thể dựa vào hành vi này với hầu hết các trình biên dịch C không? Tôi có thể mong đợi hành vi này với các trình biên dịch C++ không?

+0

C++ không đối xử với bất kỳ công đoàn nào khác với c –

+1

@UriBrecher thực sự có nhiều khác biệt –

+1

@ M.M: Vậy hãy nói rằng 'union' khác với C & C++ như thế nào? Liệt kê ra nhiều sự khác biệt Nếu bạn nghĩ vậy !!! – Destructor

Trả lời

13

Trong 6.7.2.1p16 những bảo đảm tiêu chuẩn C:

Kích thước của một liên minh là đủ để chứa lớn nhất trong số các thành viên của nó. Giá trị của tối đa là một trong những thành viên có thể được lưu trữ trong một đối tượng đoàn bất cứ lúc nào. Một con trỏ tới một đối tượng đoàn, chuyển đổi phù hợp, chỉ để mỗi người trong số các thành viên của nó (hoặc nếu một thành viên là một lĩnh vực bit-, sau đó cho đơn vị mà nó cư trú), và ngược lại.

Vì vậy, có, bạn có thể dựa vào tất cả các thành viên bắt đầu từ địa chỉ của union (lưu ý điều này giống với thành viên đầu tiên của struct).

Tiêu chuẩn C++ bao gồm một câu tương tự đối với kiểu C (nghĩa là chỉ thành viên kiểu C) union s/struct s, vì C++ cho phép chuyển các hàm union s đến C yêu cầu bố cục này. trong tiêu chuẩn C++ là 9,5.


Tuy nhiên, lưu ý có thể được đệm bit bên trong loại đơn giản chuẩn (số nguyên, nổi). Và nội bộ của họ có thể thay đổi (endianess). Bạn cũng có thể vi phạm răng cưa nghiêm ngặt quy tắc (C: hiệu quả loại).

9

Từ kinh nghiệm của tôi, tôi sẽ nói 'có', mặc dù tôi đã kiểm tra các C++14 standard và nó thậm chí còn đảm bảo này. (C++ 11 rất có thể sẽ có cùng tác dụng) Chương 9.5 nêu rõ: All non-static data members of a union object have the same address

Vì vậy, bạn có thể phụ thuộc vào hành vi này.

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