2011-06-06 28 views
16

Tôi hiện đang làm việc với mã số C++ cũ, được biên dịch thành công với g.TS. 2.9.
Tôi đã được yêu cầu chuyển mã di sản này sang gcc 3.4.X. Hầu hết các lỗi đã được sửa chữa dễ dàng, nhưng điều này đặc biệt là một câu đố tôi.Ý nghĩa của cặp dấu ngoặc kép khởi tạo C-struct là gì?

Bối cảnh:

struct TMessage 
    { 
    THeader header; 
    TData data; 
    }; 

struct THeader 
    { 
    TEnum myEnum; 
    TBool validity; 
    }; 

gì đã được thực hiện:

const TMessage init = {{0}}; 

/* Later in the code ... */ 
TMessage message = init; 

Câu hỏi của tôi (s):
ý nghĩa của {{}} nhà điều hành là gì? Liệu nó có khởi tạo trường đầu tiên (tiêu đề tiêu đề) thành số nhị phân 0 không? Nó có khởi tạo trường đầu tiên của cấu trúc thứ nhất (enum) thành (chữ) 0 không?

Lỗi 3.4.6 tôi nhận được là invalid conversion from 'int' to 'TEnum', hoặc bằng một hoặc hai cặp dấu ngoặc nhọn.

Làm cách nào tôi có thể đặt cấu trúc của mình thành một nhóm 0 mà không sử dụng memset?

Xin cảm ơn trước.

+0

Tại sao bạn chuyển mã của mình từ phiên bản cũ của gcc sang phiên bản cũ của gcc? –

+0

Để biên dịch/liên kết/thực hiện nó trên nền tảng khác. –

+0

Không biết về C++. Trong C không có lỗi (có lẽ trình biên dịch của bạn đang trở nên hữu ích đến mức sai) – pmg

Trả lời

18

Nó initialises mọi lĩnh vực của cấu trúc POD đến 0.

Lý do:

const SomeStruct init = {Value}; 

initialises trường đầu tiên của SomeStruct đến giá trị gia tăng, phần còn lại của cấu trúc bằng không (tôi quên phần trong tiêu chuẩn, nhưng đó là một nơi nào đó)

Như vậy:

const SomeOtherStruct init = {{Value}}; 

Khởi tạo trường đầu tiên của trường đầu tiên của cấu trúc (trong đó trường đầu tiên của cấu trúc chính nó là cấu trúc POD) thành Giá trị và phần còn lại của trường đầu tiên bằng 0 và phần còn lại của cấu trúc là 0.

Ngoài ra, điều này chỉ là không làm việc vì C++ cấm chuyển đổi ngầm của int để enum loại, vì vậy bạn có thể làm:

const SomeOtherStruct init = {{TEnum(0)}}; 
+1

Vì vậy, bạn đang nói 'const TMessage init = {{myEnumFirstValue}};' sẽ khởi tạo enum của tôi, sau đó mọi trường khác là 0? Nó biên dịch thành công, tôi lo ngại về thời gian chạy. dù sao cũng cảm ơn bạn ! –

+3

Phần có liên quan của tiêu chuẩn là 8.5.1.7: * Nếu có ít người khởi tạo trong danh sách hơn số thành viên trong tổng hợp, thì mỗi thành viên không được khởi tạo rõ ràng sẽ được khởi tạo giá trị. * –

+0

Phần cuối có ý nghĩa gì? _shall được value-initialized_: bởi trình biên dịch? –

1

Bạn có thể hink của nó như là một mảng đa chiều (nếu điều đó giúp). Sau đó bạn đặt lại hai thứ nguyên thành 0 bằng lệnh đó. Điều này làm việc kể từ khi (tôi giả định) rằng các giá trị trong cấu trúc có thể lấy 0 làm giá trị.

+0

Cảm ơn! Tôi đã thiếu một thực tế rằng mỗi ** ** lĩnh vực khác đã được khởi tạo đến 0, mặc dù. –

3
  • các niềng răng đầu tiên dành cho struct TMessage
  • các cú đúp thứ hai là cho struct THeader
  • Các zero đen là dành cho TEnum myEnum

Trong trường hợp này bạn đang khởi TEnum với int0, đó là incompatible conversion.

Vì vậy, bạn phải thêm đúc như thế này:

const TMessage init = {{TEnum(0)}}; 

Trong C/C++, nếu bạn partially initialized cấu trúc hoặc mảng (chỉ một số các lĩnh vực/yếu tố đầu tiên), phần còn lại sẽ được khởi tạo bởi các default constructor (đó là zero-initialization cho các kiểu nguyên thủy). Lỗi biên dịch sẽ xảy ra nếu không có hàm tạo mặc định hoặc nếu hàm tạo được khai báo là private.

+1

Không chính xác là phần còn lại sẽ luôn được khởi tạo về 0. Như tôi đã đăng trong một bình luận cho câu trả lời của @ Autopulated, chúng sẽ được * khởi tạo giá trị *. Ví dụ, nếu một thành viên thuộc kiểu lớp với một hàm tạo mặc định, thì hàm tạo đó sẽ được gọi. –

+0

@ Space_C0wb0y: Tôi đã sửa. Tôi đã chỉnh sửa câu trả lời của mình – dragon135

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