Bug 19667 – .offsetof cannot be used on non-public members of aggregates in different modules

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-02-11T04:43:10Z
Last change time
2023-07-27T18:51:51Z
Assigned to
No Owner
Creator
Adam Wilson

Comments

Comment #0 by flyboynw — 2019-02-11T04:43:10Z
Consider the following code: module mod1; public struct S { public int publicField; private int privateField; } ----- module mod2; import mod1; void main() { import std.conv : to; import std.stdio : writeln; writeln(to!string(S.publicField.offsetof)); //OK writeln(to!string(S.privateField.offsetof)); //Compiler error } This means that is impossible to correctly map the memory layout a given aggregate from outside of the implementing module using only .offsetof. I am aware that .tupleof can be used to bypass the protection checks, but using .tupleof is a hack. Why can .tupleof bypass the checks, but not .offsetof?
Comment #1 by sprink.noreply — 2019-02-18T23:23:58Z
tupleof is effective a member function of S that has access to those private fields. The returned type is a new tuple, not of type S so none of the fields are private. If you want to know the offset of you can do the same thing. struct S { public int publicField; private int privateField; public auto tupleof() { return Tuple!("publicField", publicField, "privateField", privateField); } public auto privateFieldOffsetOf() { return privateField.offsetof; } }
Comment #2 by dkorpel — 2023-07-27T18:51:51Z
Access checks can be circumvented with __traits(getMember) and tupleof for meta-programming purposes. `S.privateField` fails the access check before `.offsetof` is queried on that. Making `.offsetof` undo the access check of its operand is more hacky than using existing methods.