Use of the offsetof macro
ID |
objectivec.maintainability.avoid_offsetof |
Severity |
info |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Type Safety |
Language |
Objective-C |
Rationale
offsetof is only guaranteed to give a meaningful result for a standard-layout type, and an Objective-C class is not one: under the non-fragile ABI the runtime decides where each ivar lands and is free to move it when a superclass in a system framework grows, so an offset computed at compile time can be silently wrong on the next OS release. Even for a plain C struct the call breaks quietly if the member it names is ever reordered or moved into a nested struct, with no diagnostic at the call site.
The following code illustrates the pattern detected by this rule:
@implementation PacketReader
- (size_t)versionFieldOffset {
// FLAGGED: Use of the offsetof macro
return offsetof(struct PacketHeader, version);
}
@end
Remediation
Access the member directly through a typed pointer instead of computing its offset. Where an ivar offset genuinely must be discovered, ask the runtime for it - ivar_getOffset on the Ivar returned by class_getInstanceVariable - so the answer comes from the layout actually in force. If a byte layout must be pinned down for serialization, define a packed C struct for the wire format and document that constraint next to it.