Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6888139
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T05:58:22+00:00 2026-05-27T05:58:22+00:00

All struct s in C# by default are treated as [StructLayout(LayoutKind.Sequential)] -marked value types.

  • 0

All structs in C# by default are treated as [StructLayout(LayoutKind.Sequential)]-marked value types. So lets take some number of structs and inspect sizes of this structs:

using System;
using System.Reflection;
using System.Linq;
using System.Runtime.InteropServices;

class Foo
{
  struct E { }
  struct S0 { byte a; }
  struct S1 { byte a; byte b; }
  struct S2 { byte a; byte b; byte c; }
  struct S3 { byte a; int b; }
  struct S4 { int a; byte b; }
  struct S5 { byte a; byte b; int c; }
  struct S6 { byte a; int b; byte c; }
  struct S7 { int a; byte b; int c; }
  struct S8 { byte a; short b; int c; }
  struct S9 { short a; byte b; int c; }
  struct S10 { long a; byte b; }
  struct S11 { byte a; long b; }
  struct S12 { byte a; byte b; short c; short d; long e; }
  struct S13 { E a; E b; }
  struct S14 { E a; E b; int c; }
  struct S15 { byte a; byte b; byte c; byte d; byte e; }
  struct S16 { S15 b; byte c; }
  struct S17 { long a; S15 b; }
  struct S18 { long a; S15 b; S15 c; }
  struct S19 { long a; S15 b; S15 c; E d; short e; }
  struct S20 { long a; S15 b; S15 c; short d; E e; }

  static void Main()
  {
    Console.WriteLine("name: contents => size\n");
    foreach (var type in typeof(Foo).GetNestedTypes(BindingFlags.NonPublic))
    {
      var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
      Console.WriteLine("{0}: {2} => {1}", type.Name, Marshal.SizeOf(type),
        string.Join("+", fields.Select(_ => Marshal.SizeOf(_.FieldType))));
    }
  }
}

Output is (the same on x86/x64):

name: contents => size

E:  => 1
S0: 1 => 1
S1: 1+1 => 2
S2: 1+1+1 => 3
S3: 1+4 => 8
S4: 4+1 => 8
S5: 1+1+4 => 8
S6: 1+4+1 => 12
S7: 4+1+4 => 12
S8: 1+2+4 => 8
S9: 2+1+4 => 8
S10: 8+1 => 16
S11: 1+8 => 16
S12: 1+1+2+2+8 => 16
S13: 1+1 => 2
S14: 1+1+4 => 8
S15: 1+1+1+1+1 => 5
S16: 5+1 => 6
S17: 8+5 => 16
S18: 8+5+5 => 24
S19: 8+5+5+1+2 => 24
S20: 8+5+5+2+1 => 24

Looking at this results I can’t understand the layout (fields aligning and total size) ruleset CLR used for sequential structs. Can somebody explain me this behavior?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T05:58:23+00:00Added an answer on May 27, 2026 at 5:58 am

    All the fields are aligned depending on their type. The native types (int, byte, etc.) are all aligned by their size. For example, an int will always be at a multiple of 4 bytes in, while a byte can be anywhere.

    If smaller fields come before an int, padding will be added if necessary to ensure the int is properly aligned to 4 bytes. This is why S5 (1+1+4 = 8) and S8 (1+2+4 = 8) will have padding and end up the same size:

    [1][1][ ][ ][4] // S5
    [1][ ][ 2  ][4] // S8
    

    Additionally, the struct itself inherits the alignment of its most-aligned field (ie. for S5 and S8, int is the most-aligned field, so both of them have an alignment of 4). Alignment is inherited like this so that when you have an array of structs, all the fields in all the structs will be properly aligned. So, 4+2 = 8.

    [4][2][ ][ ] // starts at 0
    [4][2][ ][ ] // starts at 8
    [4][2][ ][ ] // starts at 16
    

    Notice the 4 is always aligned by 4. Without inheriting from the most-aligned field, every other element in an array would have its int aligned by 6 bytes instead of 4:

    [4][2] // starts at 0
    [4][2] // starts at 6 -- the [4] is not properly aligned!
    [4][2] // starts at 12
    

    This would be very bad because not all architectures allow reading from unaligned memory addresses, and even the ones that do have a (potentially quite large, if on a cache line or page boundary) performance penalty for doing it.

    Beyond basic performance, alignment also comes into play with concurrency. The C# memory model guarantees reads/writes of the native types up to 4 bytes wide are atomic, and .NET has atomic features like the Interlocked class. Atomic operations like these boil down to CPU instructions that themselves require aligned memory access to work.

    Proper alignment is very important!

    You will often see clever native coders keep all of this in mind while laying out their structures, sorting all fields from largest to smallest in an effort to keep padding, and thus struct size, to a minimum.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Duplicate: Why Must I Initialize All Fields in my C# struct with a Non-Default
Should all structs and classes be declared in the header file? If I declare
I tend to take the academic approach all too often and adhere to strict
C# doesn't allow structs to derive from classes, but all ValueTypes derive from Object.
I've looked for overriding guidelines for structs, but all I can find is for
First of all the Boolean type is said to have a default marshal type
I have never written a stateful IComparer<T> with a default constructor. All standard library
Is there a way to have some kind of default constructor (like a C++
In .NET, a value type (C# struct ) can't have a constructor with no
Consider the following routine, which simplifies life for me by building in some default

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.