D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 15965 - [REG 2.070] Reference to other CT-known field on struct instantiation now yields "circular reference"
Summary: [REG 2.070] Reference to other CT-known field on struct instantiation now yie...
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 regression
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-28 16:53 UTC by Mathias Lang
Modified: 2016-05-11 20:09 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Mathias Lang 2016-04-28 16:53:26 UTC
Here's an extract of a piece of code we had:

```
struct Element
{
    public ubyte[256] val;
    private ubyte[(val.offsetof + 256) % size_t.sizeof] _padding;
}
```

This used to compile up until 2.071.0, where it broke.

Is it an intentional change, and is it expected that accessing `offsetof` during struct instantiation now fails ?
Comment 1 Kenji Hara 2016-05-06 14:09:42 UTC
First, is the summary "[REG 2.070] ..." a mistake of REG-master (or REG-devel, etc)? 

You've said:

> This used to compile up until 2.071.0, where it broke.

So the *issue* exists only in current master branch that not yet released as 2.072.

----

The displayed error with git-head dmd is:

test.d(4): Error: struct test.Element no size because of forward reference

And yes it is an intentional change. Until 2.071, an use of 'offsetof' property during declarations of instance fields has returned 0 always. Next is an example of the bug:

struct Element
{
    ubyte x;    // add a field before Element.val

    public ubyte[256] val;

    // printed 0 until 2.071, it was incorrect
    pragma(msg, "1: ", val.offsetof);

    private ubyte[(val.offsetof + 256) % size_t.sizeof] _padding;
}

// After Element struct fields are determined, offsetof can return correct result
pragma(msg, "2: ", Element.val.offsetof);

// If val.offsetof correctly returned 1 during declaration of _padding,
// this pragma(msg) would have printed 1, but actually it printed 0...
pragma(msg, Element._padding.sizeof);

To disallow use of incorrect offsetof value, the "no size bevause of ..." error was introduced.

----

Although the master change is intentional, I still think compiler would be able to supply correct offset value in the OP case. In other words, I think we can change this issue to an enhancement request.
Comment 2 Mathias Lang 2016-05-09 10:54:51 UTC
> First, is the summary "[REG 2.070] ..." a mistake of REG-master (or REG-devel, etc)? 

It stopped compiling when I tried 2.071. Do you use the version of the last working compiler, or the first broken one ? I want with the last working one, but according to your comment it should probably be [REG 2.071]` then.


In the presented case, it would probably work, but since it's highly dependent of the order of declaration, I don't know if it's worth supporting it. I'm pretty sure anything achievable by mean of `offsetof` is achievable by mean of `sizeof` + `align`.

TL;DR:
We fixed the issue in our code, and I don't find the breakage unreasonable.
We reported the issue for documentation purpose, because the code broke. But looks like it was already broken before anyway.
Closing as WONTFIX, feel free to reopen if you think it's worth enhancing.
Comment 3 Dicebot 2016-05-11 20:09:23 UTC
I think it is one of few cases where immediate breakage is indeed legitimate.