Jump to page: 1 2 3
Thread overview
[Issue 3449] New: const and invariant struct members do not behave according to spec
Oct 29, 2009
Stewart Gordon
Oct 30, 2009
Stewart Gordon
Jun 16, 2011
yebblies
Nov 24, 2011
Walter Bright
Nov 24, 2011
Stewart Gordon
Jan 23, 2012
Walter Bright
Jan 23, 2012
Walter Bright
Jan 23, 2012
Kenji Hara
Jan 23, 2012
Stewart Gordon
May 12, 2012
Masahiro Nakagawa
Jul 25, 2012
David Piepgrass
Jul 25, 2012
Stewart Gordon
Jul 26, 2012
David Piepgrass
Jul 26, 2012
Stewart Gordon
Dec 26, 2012
Andrej Mitrovic
Dec 27, 2012
Andrej Mitrovic
Dec 28, 2012
Andrej Mitrovic
Mar 10, 2013
Walter Bright
Apr 06, 2013
Andrej Mitrovic
May 13, 2013
Kenji Hara
May 25, 2013
Walter Bright
May 26, 2013
Walter Bright
October 29, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3449

           Summary: const and invariant struct members do not behave
                    according to spec
           Product: D
           Version: 2.035
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: bugzilla@kyllingen.net


--- Comment #0 from Lars T. Kyllingstad <bugzilla@kyllingen.net> 2009-10-29 04:52:34 PDT ---
When struct members are declared const or invariant, they seem to become manifest constants. Example:

  struct Foo { const int bar = 123; }
  writeln(Foo.sizeof);   // Prints "1", not "4"

  Foo foo;
  auto p = &foo.bar;     // Error: constant 123 is not an lvalue

The same happens if const is replaced with immutable. According to the spec it should be possible to take the address of const/immutable variables, and in the case of const it is even considered well-defined behaviour to change their value after casting them to non-const. I see no reason why this shouldn't apply to structs as well.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 29, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3449


Stewart Gordon <smjg@iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg@iname.com


--- Comment #1 from Stewart Gordon <smjg@iname.com> 2009-10-29 15:08:09 PDT ---
(In reply to comment #0)
> and in the case of const it is even considered well-defined behaviour to change their value after casting them to non-const.

What bit of the spec is this?  Are you sure you aren't confusing D with C(++)?

But the rest of what you say is probably right.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3449



--- Comment #2 from Lars T. Kyllingstad <bugzilla@kyllingen.net> 2009-10-29 23:35:28 PDT ---
(In reply to comment #1)
> (In reply to comment #0)
> > and in the case of const it is even considered well-defined behaviour to change their value after casting them to non-const.
> 
> What bit of the spec is this?  Are you sure you aren't confusing D with C(++)?

You're right, I got things mixed up there. :)

On the "const and immutable" page there is a section named "Removing Immutable With A Cast", where it says that "The immutable type can be removed with a cast [...] This does not mean, however, that one can change the data". It says nothing about const, which was what led me to believe that changing consts is not illegal, at least.

But I see now that the D/C++ comparison table at the bottom of the page has a similar statement for consts.

But the rest still stands: It should be possible to take the address of both consts and immutables.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3449



--- Comment #3 from Stewart Gordon <smjg@iname.com> 2009-10-30 06:39:03 PDT ---
(In reply to comment #2)
> (In reply to comment #1)
>> (In reply to comment #0)
>>> and in the case of const it is even considered well-defined behaviour to change their value after casting them to non-const.
>> 
>> What bit of the spec is this?  Are you sure you aren't confusing D with C(++)?
> 
> You're right, I got things mixed up there.  :)
> 
> On the "const and immutable" page there is a section named "Removing Immutable With A Cast", where it says that "The immutable type can be removed with a cast [...] This does not mean, however, that one can change the data".  It says nothing about const, which was what led me to believe that changing consts is not illegal, at least.

Since immutable is implicitly convertible to const, it's reasonable that the same rule should apply to const.

My guess is that the reason for being able to cast away const/immutable is to interface APIs that take pointers to mutable because they _may_ change the data, but which can be controlled not to.  The Windows API function DrawTextEx is an example of this.

But I do wish the means of casting away const/immutable were explicit - see http://tinyurl.com/yzzbgdn

> But I see now that the D/C++ comparison table at the bottom of the page has a similar statement for consts.
> 
> But the rest still stands: It should be possible to take the address of both consts and immutables.

Agreed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3449


Lars T. Kyllingstad <bugzilla@kyllingen.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |major


--- Comment #4 from Lars T. Kyllingstad <bugzilla@kyllingen.net> 2010-09-21 04:43:38 PDT ---
More strangeness:  If you don't explicitly provide an initial value for const/immutable members, they do contribute to the size of the struct.

    struct Foo { const int i; }
    writeln(Foo.sizeof); // Prints 4

    struct Bar { const int i = 123; }
    writeln(Bar.sizeof); // Prints 1

I suspect that this bug could cause unexpected memory corruption when such structs are, for instance, passed to C functions -- especially when the behaviour depends on such a small detail.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 03, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3449


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #5 from bearophile_hugs@eml.cc 2010-11-03 04:33:09 PDT ---
This is an important bug. See also the threads:

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=22540

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=120910

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 16, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=3449


yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch
                 CC|                            |yebblies@gmail.com


--- Comment #6 from yebblies <yebblies@gmail.com> 2011-06-15 20:33:41 PDT ---
https://github.com/D-Programming-Language/dmd/pull/93

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 24, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=3449


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #7 from Walter Bright <bugzilla@digitalmars.com> 2011-11-24 00:50:02 PST ---
I believe the correct solution is to make const/immutable fields with initializers into static members. Without initializers, they are per-instance fields, and must be initialized by the constructor.

If the user wants manifest constants in a struct/class, use enum.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 24, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=3449



--- Comment #8 from Stewart Gordon <smjg@iname.com> 2011-11-24 04:14:00 PST ---
(In reply to comment #7)
> I believe the correct solution is to make const/immutable fields with initializers into static members.

Changing this would alter the memory layout of the struct, thereby breaking code that interfaces (for example) a C API or a binary file format.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 23, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=3449



--- Comment #9 from Walter Bright <bugzilla@digitalmars.com> 2012-01-23 01:37:27 PST ---
(In reply to comment #4)
> More strangeness:  If you don't explicitly provide an initial value for
> const/immutable members, they do contribute to the size of the struct.
>     struct Foo { const int i; }
>     writeln(Foo.sizeof); // Prints 4
>     struct Bar { const int i = 123; }
>     writeln(Bar.sizeof); // Prints 1

This is as designed. A const field without an initializer can be initialized by a constructor. A const field with an initializer does not need any per-instance storage, and becomes a static member.

> I suspect that this bug could cause unexpected memory corruption when such structs are, for instance, passed to C functions -- especially when the behaviour depends on such a small detail.

It is not a bug, it is as designed. (const in D and C are different, and conflating the two will cause problems anyway)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2 3