Search code examples
c#.netmemorystructcil

Is changing the size of a struct a breaking change in C#?


Just curious, is changing the size of a struct/value type a breaking change in C#? Structs tend to be more sensitive in terms of memory layout since altering them directly affects the size of arrays/other structs. Are there any examples of code that breaks, either binary-wise or source-wise, after the layout of a struct in a library it uses is changed?

NOTE: By "breaks," I mean it fails to compile at all or the IL is invalidated. So for example I wouldn't consider this a breaking change:

// My.Library v1
public struct MyStruct {}

// My.Library v2
public struct MyStruct { int _field; }

// App code
using My.Library;
using System.Runtime.InteropServices;

Console.WriteLine(Marshal.SizeOf<MyStruct>()); // before printed 1, now prints 4

because it still runs.


Solution

  • Changing size by adding fields is ok for strictly managed code.

    Adding field(s) is non-breaking change as code will be re-JIT-ed with the new type and all allocations will use correct size. Since it is value type the new fields will be properly initialized with empty values anyway.

    Removing/changing types of existing fields(s) or properties is definitely breaking change.

    Value types are sealed - so no other libraries can derive from that type - so unlike classes they can't create problems with "this derived class did not implement a new virtual property/interface method".

    Note: if a value type is used for interop or any other kind of binary serialization outside of your control than any change is breaking.

    I.e. someone else used MyLib.Point {int x;int y;} to save a list of points with binary serialization to a file. If now "MyLib" adds a new field to MyLib.Point than the serialized data no longer can be read with binary serialization. Similar issue with native interop.