2016-03-30 29 views
6

Nói rằng tôi đã có loại này:Có an toàn để tham khảo cấu trúc đang được khởi tạo trong trình khởi tạo của nó không?

struct Bitmap 
{ 
    int w, h, *b; 
}; 

Tôi khởi tạo nó như thế này:

int w = 7, h = 4; 
struct Bitmap bmp = {w, h, calloc(bmp.w * bmp.h, sizeof(*bmp.b))}; 

Có đảm bảo rằng trình biên dịch sẽ khởi tạo struct tuần tự? Tôi có thể chắc chắn rằng vào thời điểm trường bmp.b đang được khởi tạo, các trường bmp.wbmp.h đã được khởi tạo chưa?

+0

Tại sao thứ tự quan trọng? – chux

+0

BTW, nên chắc chắn rằng sản phẩm được tính toán bằng cách sử dụng 'size_t' math:' bmp.w * bmp.h' -> '(size_t) bmp.w * bmp.h'. – chux

+0

Nếu trường 'bmp.b' đang được khởi tạo trước, thì các trường' bmp.w' và 'bmp.h' chứa rác tại thời điểm khởi tạo' bmp.b', và do đó giống như 'calloc (-542 *) 3546, sizeof (* bmp.b)) 'có thể xảy ra. –

Trả lời

8

Sử dụng

Bitmap bmp = {w, h, calloc(bmp.w * bmp.h, sizeof(*bmp.b))}; 

là hành vi không xác định. Có hai mục trong tiêu chuẩn C99 giải quyết vấn đề này.

6.7.8. Khởi

...

19 Việc khởi sẽ xảy ra theo thứ tự danh sách initializer, mỗi initializer cung cấp cho một subobject đặc biệt trọng bất kỳ initializer được liệt kê trước đó cho subobject cùng.

...

23 Thứ tự mà bất kỳ tác dụng phụ xảy ra một trong những biểu hiện danh sách khởi tạo là unspecified.133)

và chú thích 133 nói:

Đặc biệt, thứ tự đánh giá không cần phải giống với thứ tự khởi tạo subobject

Cùng với nhau, ý nghĩa của chúng là bmp.w sẽ được khởi tạo trước bmp.h. Tuy nhiên, có thể là calloc(bmp.w * bmp.h, sizeof(*bmp.b)) được đánh giá trước bmp.wbmp.h được khởi tạo. Do đó hành vi không xác định.

2

Không, không an toàn.

Quoted from N1570 6.7.9 Khởi, tôi nhấn mạnh:

23 Các đánh giá của các biểu thức danh sách khởi tạo được indeterminately trình tự liên quan đến nhau và do đó các thứ tự mà bất kỳ tác dụng phụ xảy ra không được chỉ định.

Trong code của bạn, calloc(bmp.w * bmp.h, sizeof(*bmp.b)) không được đảm bảo để được đánh giá trước bmp.wbmp.h được khởi tạo. Điều này có nghĩa bạn phải viết

int w = 7, h = 4, *b = calloc(w * h, sizeof *b); 
struct Bitmap bmp = {w, h, b}; 

hoặc

struct Bitmap bmp = {w, h, calloc(w * h, sizeof *b)}; 
+0

bmp không được xác định trong dòng đầu tiên, vì vậy nó phải là '* b = calloc (w * h, sizeof (* b)); ' – RomCoo

+0

@RomCoo Cảm ơn bạn đã chỉ ra rằng –

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