IronLanguages / IronLanguages/ironpython3

Bitfield alignment rules used by gcc are unsupported

Open
#1,442 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

module-ctypes posix
Dominant language
C#
Stars
2.8k
Forks
316
Avg merge
1d 9h
Merged PRs (30d)
1

Description

IronPytthon always uses msvc bitfield alignment rules for bitfields in structures in ctypes. According to these rules, a different type of a bitfield from the preceding one forces the compiler to align the new bitfield at its type's alignment boundary. On Windows, these are also the rules used by CPython.

On Unix platforms, however, CPython uses gcc alignment rules, which say that bitfields may be absorbed in the subsequent or preceding wider type, if they fit.

Example:

from ctypes import *

class X(Structure):
    _fields_ = [
                ("a", c_byte, 4),
                ("b", c_byte, 6),
                ("c", c_short, 2),
               ]

print(sizeof(X))

IronPython (and CPython on Windows):
The structure size is 4. Although a and b have the same type, both do not fit in a single byte so b is aligned with the next byte. Hence both fields take 2 bytes. c has a different type than the preceding bitfield so it is also aligned at the next byte boundary so it adds 2 bytes to the overall size.

CPython (on Linux/macOS)
The structure size is 3. b cannot be placed in the same bye as a because their joint width (4+6) is more than 8 bits for a byte. So a is the sole bitfield in the first byte of the structure. But b can be (and is) merged with c because their joint width (6 + 2) fits within 16 bits of a short int. This adds 2 bytes for the short int hosting both b and c. Note that this merging also happens if the order of b and c is reversed or if other integer types are used.

As a workaround, ctypes structures depending on this type of compiler behaviour should be declared with all absorbed narrower fields to be of the type of the absorbing field. In the example above, declare b as c_short.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No implementation files or tests are named. Start by locating the ctypes Structure bitfield layout entry point and existing bitfield tests, then compare the example's layout with CPython on Unix. Done means the relevant ctypes structures follow the described GCC-compatible alignment behavior without regressing Windows rules.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.