2014-09-15 15 views
18

Sử dụng F # Interactive, bạn có thể xác minh các kích thước sau:Tại sao cấu trúc chung F # có trường __dummy thừa?

// sizeof<A> = 4 bytes 
type A (i: int) = struct end 

// sizeof<B<int>> = 8 bytes (use any type parameter) 
type B<'T> (i: int) = struct end 

Lý do kích thước thêm vẻ là sự hiện diện của một __dummy trường số nguyên trong trường hợp tổng quát. Sử dụng F # Interactive một lần nữa, bạn có thể thấy điều này bằng typeof:

  • typeof<A> lãm DeclaredFields = [|Int32 i|]
  • typeof<B<int>> lãm DeclaredFields = [|Int32 i; Int32 __dummy|]

Tôi không hiểu tại sao lĩnh vực __dummy này đã được thêm vào.

Tôi nghĩ rằng mã chịu trách nhiệm cho việc thêm nó là ở đây:

https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/ilxgen.fs

Line 6377 thấy điều này:

if requiresExtraField then 
    yield mkILInstanceField("__dummy",cenv.g.ilg.typ_int32,None,ILMemberAccess.Assembly) ] 

Line 6290 là nơi requiresExtraField được định nghĩa:

let requiresExtraField = 
    let isEmptyStruct = 
     (match ilTypeDefKind with ILTypeDefKind.ValueType -> true | _ -> false) && 
     // All structs are sequential by default 
     // Structs with no instance fields get size 1, pack 0 
     tycon.AllFieldsAsList |> List.exists (fun f -> not f.IsStatic) 

    isEmptyStruct && cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty 

tôi giả sử rằng isEmptyStruct được cho là có nghĩa là cấu trúc không có bất kỳ trường mẫu nào. Nhưng mã như được viết là kiểm tra xem cấu trúc có bất kỳ trường mẫu nào không, cho hầu hết các cấu trúc, kể cả của tôi, sẽ là đúng. Tôi nghĩ phần cuối cùng của bài kiểm tra cuối cùng là liệu có bất kỳ tham số kiểu chung nào không. Vì vậy, requiresExtraFieldfalse cho type A (không phải chung chung) và true cho type B (loại chung).

Đây có phải là lỗi trình biên dịch hay mã đúng không? Nếu đúng, thì mục đích của trường __dummy này là gì? Có cách nào tôi có thể tránh được không?

Như thử nghiệm khác, tôi lấy ra một của tôi và instance field chỉ, và không đáng ngạc nhiên, tôi có các kích thước sau, cho thấy rằng lĩnh vực __dummy đã không còn nói thêm:

// sizeof<AA> = 1 
type AA = struct end 

// sizeof<BB<int>> = 1 
type BB<'T> = struct end 

Lý do tôi muốn có một loại giá trị, chứ không phải là một kiểu tham chiếu, là tôi sẽ lưu trữ rất nhiều các đối tượng này trong các cấu trúc dữ liệu của tôi, không chỉ truyền chúng xung quanh.

+0

"cenv.opts.workAroundReflectionEmitBugs" gợi ý rằng đây là giải pháp cho một số lỗi phát ra phản chiếu. Bạn đã kiểm tra xem C# có thực hiện điều tương tự không? - Xem nhanh lịch sử mã cho thấy ngày này trở lại ít nhất là tháng 11 năm 2010, F # 2.0 - phiên bản sớm nhất của mã có sẵn trực tuyến AFAIK. – Asik

+1

Kể từ khi sizeof > = 4 trong một chương trình, là kích thước của nó trong tương tác thực sự là một vấn đề cho bạn? – jyoung

+0

@ jyoung: Ồ, tôi chưa bao giờ nhận ra rằng đây chỉ là trường hợp với F # Interactive. Tôi chỉ thử sizeof > trong một chương trình, như bạn đã nói, và nó cho 4, trong khi F # Interactive cho 8. Sau đó, vấn đề của tôi được giải quyết, cảm ơn bạn! Tôi thấy rằng tập tin nguồn bằng cách sử dụng Google, vì vậy tôi không biết hình ảnh lớn hơn của nó là gì. Trong tệp fsi tương ứng, loại công khai 'IlxAssemblyGenerator' ở cuối cho biết rằng nó là _An máy phát mã ILX gia tăng cho một assembly_ duy nhất. Chỉ để chỉnh sửa của tôi, đó là tất cả những gì về? – bananasareyellow

Trả lời

1

Giải thích được đưa ra bởi @jyoung trong các nhận xét bên dưới bài đăng gốc của tôi.

Dòng cuối cùng của requiresExtraField cũng kiểm tra cenv.opts.workAroundReflectionEmitBugs. Cờ này dường như được đặt trong fscopts.fs. Dòng mã là:

workAroundReflectionEmitBugs=tcConfig.isInteractive; // REVIEW: is this still required? 

Vì vậy, vấn đề của trường bổ sung __dummy chỉ xảy ra trong F # Interactive.

+0

Điều này không trả lời câu hỏi liệu logic của 'isEmptyStruct' có ngược lại hay không. – ildjarn

+0

@ildjarn: Bạn nói đúng, nó không có. Tôi đánh dấu nó là đã trả lời vì vấn đề nguyên tắc của tôi là kích thước của cấu trúc do sự hiện diện của trường giả. Thử nghiệm đó vẫn còn đáng nghi. – bananasareyellow

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