About foreach loops

Jesse Phillips jessekphillips+D at gmail.com
Fri Jun 17 17:49:50 PDT 2011


Timon Gehr Wrote:

> I will now do the same thing you did: Yes I know where it resides, I can
> disassemble the resulting executable and there is the address, plain as day!

Not possible, the executable can not contain an address because nothing is in memory to have an address.

> JK, I guess you did not realize there was a "...and mutating the memory" part in
> my statement? =)

I did see that but you must first understand that casting away const is defined. Once this is done though the compiler can no longer identify when something that was once const is now being modified.

The behavior of modifying an int* is also defined, and when you cast away const to get an int* you maybe modifying what use to be a const variables, but the compiler does not know that.
 
> > at compile time. The compiler doesn't know where in memory the values are stored
> I think you did not understand the point. The compiler does not have to check
> anything (and why do you think it is not allowed to?), to provide that guarantee.
> It just has to act as (following you example below) DMD does at the moment. But
> the spec has to reflect this, otherwise, a complying compiler can do anything.

No it can not provide that guarantee at no cost. It is allowed to do optimizations on const variables, I can not tell what optimizations the compiler could preform as I don't think there are any at this time, but why restrict future geniuses?

Sorry shouldn't have brought up extra code, if you can come up with some code or design that can identify when a const value has changed, within the current guidelines of the spec the more power to you.

> My examples are not flawed, that is what the discussion was about in the
> beginning: rewriting the foreach range loop into the second example. Then
> bearophile protested.

This is an implementation detail of foreach that can be made to work with DMD.

Though this does bring up a point you aren't trying to make. There are places where the compiler can statically identify you are modifying const and put in any code it wants, but it still can't define what happens when you modify const.

> 
> >
> > void main(){
> >     int a = 53;
> >     const int* pa = &a;
> >     auto pb = cast(int*) pa;
> >     assert(*pb == *pa);
> >     *pb = 3;
> >     assert(*pb == *pa);
> > }
> >
> > This will always be true on every implementation.
> 
> No. Not as long as the behavior is undefined.

Yes even if it is undefined.
 
> As long as the spec does not define what
> happens if you modify const, _the compiler can do anything!_. Does not mean that
> it will do anything specific, such as that what you'd like it to do, just that
> theoretically, it *could* format your hard drive, call your grandma, or steal your
> identity without breaking language imposed rules.

You are correct, that it could theoretically do all those things and still be valid to the spec. But it can't be done, not without breaking some other aspect of the spec.
 
> You may want to have a look at the excellent series about the topic located at
> http://blog.regehr.org/archives/213
> 
> When I am talking about undefined behavior, I mean this.

Yes I've read his posts. And many of them the compiler knows what is happening or the hardware is even able to detect the behavior. But in the case of modifying const, you can't identify it to make it defined.

I haven't been touching on the main reason it isn't defined, could be an immutable value. You are just asking for defining when it does point to a mutable value. It is like trying to define gravity as the force that keeps you on the earth. It does do a good job of that but only because of the properties of gravity.


More information about the Digitalmars-d mailing list