October 29, 2005
Dave wrote:
> In article <djssee$1b40$1@digitaldaemon.com>, Bruno Medeiros says...
> 
>>Dave wrote:
>>
>>>So, for stack alloc. classes (excluding RAII), couldn't an ...
>>
>>Walter has said this here before: stack allocated classes/objects and RAII classes/objects are *the same*. There is no stack allocated classes/objects that are not RAII.
>>
>>
>>>In article <djrt8q$2o2o$1@digitaldaemon.com>, Walter Bright says...
>>>
>>>>"Sean Kelly" <sean@f4.ca> wrote in message
>>>>Would such
>>>>
>>>>
>>>>>a design support returning classes by value?  ie.
>>>>>
>>>>>MyClass getInstance() {
>>>>>MyClass c = MyClass();
>>>>>return c;
>>>>>}
>>>>
>>>>Returning references to stack variables is wrong, wrong, wrong <g>.
>>>>
>>
>>"Would such a design support returning classes by value?"
>>Why did everyone suddenly started talking about implementind value semantics for classes? It has nothing to do with the current design/issue (which is RAII and auto-type). Just because the new RAII proposal has a syntax similiar to C++'s value objects, it doesn't mean they are anywhere near the same.
>>
>>
>>
>>>What happens with structs now? They are copied by value, but are not deep
>>>copied. ...
>>
>>What follows is a reply to also some other comments in others posts:
>>Structs have value semantics because they are structs, *not because* they are stack allocated. Thus just because we have stack allocated 
> 
> 
> Yep, but classes having value semantics was not necessarily what I was implying.
> 
Ah then, that changes things.

> 
>>objects (RAII) doesn't mean they should have value semantics as well!
> 
> 
> I'm not really asking for value semantics, I'm asking /if/ classes allocated on
> the stack can be returned 'safely' in a defined way, and I suggested a way to
> implement it that would basically allow the same syntax whether or not a class
> object was heap or stack allocated.
> 
> 
>>D's objects follow a reference model (all of them), and any discussion 
> 
> 
> No, they don't - structs can be considered 'objects' as can any native type -
> especially when you consider the implications of the current design on generic
> programming techniques. For example, for many algorithms you would have to
> develop two sets of templates or use compiler conditionals like static if
> everywhere to support both class and struct 'objects' with the same template
> declarations. That is not what I'd like to call 'generic' programming.
> 
I wasn't saying that structs should have value semantics. Just that they now have value semantics, and that it wasn't because they were stack allocated.

> 
>>regarding that, is off-topic for this thread.
>>
> 
> 
> Huh? Asking whether or not the new syntax that Walter put out here and has been
> recently discussed (and replied to) would let us return class objects allocated
> on the stack is completely within the context of this discussion since it was
> not real clear whether or not RAII and/or class object stack allocation would
> require 'auto' declaration or not.
> 
Yes, in that case (since you weren't talking about value-semantics), it is relevant.

-- 
Bruno Medeiros - CS/E student
"Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
October 29, 2005
Bruno Medeiros wrote:
> Walter Bright wrote:
>> It's implementing class objects on the stack with the:
>>     classname(constructor arguments)
>> syntax. Then, an RAII class object would be:
>>
>>     auto c = classname(arguments);
>>
>> and a non-RAII class object would be:
>>
>>     auto c = new classname(arguments);
>>
>> and the old RAII syntax would be supported as:
>>
>>     auto classname c = new classname(arguments);
>>
>> and eventually deprecated.
>>
>>
 ...
> 
> Now, as for possible alternative solutions, I don't like that proposed one either. Doesn't read that well, and it still has the homonymous keywords.
> 
I want to withdraw this opinion. I don't think I understood the new proposal correctly the first time. It seems to me this is a good alternative, even better than my similar 'autonew/snew' one. For the sake of no misundertansdings, I mean this:

  auto foo = Foo(arguments);     // auto-type, RAII
  auto foo = new Foo(arguments); // auto-type, non-RAII (heap/GC)
  Foo foo = Foo(arguments);      // explicit type, RAII
  Foo foo = new Foo(arguments);  // explicit type, non-RAII (heap/GC)


-- 
Bruno Medeiros - CS/E student
"Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
October 29, 2005
"James Dunne" <james.jdunne@gmail.com> wrote in message news:djun8f$1ht$1@digitaldaemon.com...
> Well, I think the case is exceptional for IEEE floating point types in D.
If I
> assume correctly, you've initialized them to _quiet_ NaNs so that it'd be
easy
> to detect when they are used in their "uninitialized" state.  Since the
IEEE
> spec defines that no _signaling_ NaN will be produced by any floating
point
> operation, and that SNaNs are strictly for assignment purposes, it seems
logical
> to initialize floating point values to signaling NaNs instead of quiet
NaNs.
> I'm sure you're well aware of this, and perhaps it might have been a minor oversight.  However, if there was some conscious decision made as whether
to use
> QNaNs over SNaNs I'd be interested to hear some reasoning.

I essentially gave up on the SNAN/QNAN distinction because it was too often unsupported.

> FWIW, I'm not that well read on the topic of the IEEE standard, but I did
do my
> homework! =)  I came across 'rumors', if you will, that supporting
signaling
> NaNs is tough to do in implementation because I guess the spec is unclear
on
> specific details of implementation and certain usage cases.

It isn't hard to do the implementation. The hard thing is that too much software out there ignores the distinction, and nearly all documentation makes no distinction. It's just too frustrating.

> >When I needed to use printf in a DLL with no console, I'd have the printf write to a file. That worked well.
> Thought of doing that, yes...
>
> >> Anyway, I think my point still stands.  Use of uninitialized variable warning, please?  Or perhaps a way to trap usage of a NaN in a calculation and break into the debugger - THAT would make debugging
MUCH
> >> faster, i.e. use SNANs instead of QNANs (signaling/noisy vs. quiet).
> >
> >Some strategically placed assert(!isnan(x)) expressions should help.
>
> Yes, but hopefully catching a floating-point exception from usage of a
signaling
> NaN would track it down even better... ?

No, all the signal does is set a flag FE_EXCEPT. Not too useful.


October 29, 2005
Walter Bright wrote:
> It isn't hard to do the implementation. The hard thing is that too
> much software out there ignores the distinction, and nearly all
> documentation makes no distinction. It's just too frustrating.

...

>> NaN would track it down even better... ?
> 
> No, all the signal does is set a flag FE_EXCEPT. Not too useful.

Hmm. Seems to me inserting tests for FE_EXCEPT and then throwing wouldn't bee too hard? Of course it would slow non-release floating point code significantly, but I don't see that as a major problem.

Granted, if we use bad (non-D) libraries, then we're out of luck, but the point here is to make it easy to write robust floating point libraries in D. As well as robust applications.

Somehow I can't help feeling this should be easier to implement than bounds checking. Or then I've misunderstood something. :-)
October 30, 2005
"Georg Wrede" <georg.wrede@nospam.org> wrote in message news:4363EFF5.20203@nospam.org...
> > No, all the signal does is set a flag FE_EXCEPT. Not too useful.
>
> Hmm. Seems to me inserting tests for FE_EXCEPT and then throwing wouldn't bee too hard? Of course it would slow non-release floating point code significantly, but I don't see that as a major problem.

No, it wouldn't be too hard. But it wouldn't be any easier than doing
assert(!isnan(x));

> Granted, if we use bad (non-D) libraries, then we're out of luck, but the point here is to make it easy to write robust floating point libraries in D. As well as robust applications.
>
> Somehow I can't help feeling this should be easier to implement than bounds checking. Or then I've misunderstood something. :-)


October 31, 2005
Walter Bright wrote:
> "Georg Wrede" <georg.wrede@nospam.org> wrote in message
> news:4363EFF5.20203@nospam.org...
> 
>>>No, all the signal does is set a flag FE_EXCEPT. Not too useful.
>>
>>Hmm. Seems to me inserting tests for FE_EXCEPT and then throwing
>>wouldn't bee too hard? Of course it would slow non-release floating
>>point code significantly, but I don't see that as a major problem.
> 
> 
> No, it wouldn't be too hard. But it wouldn't be any easier than doing
> assert(!isnan(x));

So, the bright boy from the plains asks the weathered seaman "we'd need a power winch at this point on the deck" and the seaman answers "you'd only need it late in the afternoon when everybody is drunk, or at night in the storm when everybody is too exhausted to think clearly".

I step back.

>>Granted, if we use bad (non-D) libraries, then we're out of luck, but
>>the point here is to make it easy to write robust floating point
>>libraries in D. As well as robust applications.
>>
>>Somehow I can't help feeling this should be easier to implement than
>>bounds checking. Or then I've misunderstood something. :-)
October 31, 2005
Sean Kelly wrote:
> From what you're saying, this sounds like it would produce undefined behavior.
> And in large function calls, this could be an easy mistake to make.  Why omit
> the need for pointer semantics for heap-based classes?  I'd think it would offer
> a degree of checking that the handle-based syntax doesn't:
> 
> MyClass* getInstance() {
> MyClass c = MyClass();
> return c; // error: cannot convert MyClass to MyClass*
> }

...and by that time D's metamorphosis into C++ will be complete.

-- 
Niko Korhonen
SW Developer
October 31, 2005
Walter Bright wrote:
> "Georg Wrede" <georg.wrede@nospam.org> wrote in message
> news:4363EFF5.20203@nospam.org...
> 
>>>No, all the signal does is set a flag FE_EXCEPT. Not too useful.
>>
>>Hmm. Seems to me inserting tests for FE_EXCEPT and then throwing
>>wouldn't bee too hard? Of course it would slow non-release floating
>>point code significantly, but I don't see that as a major problem.
> 
> 
> No, it wouldn't be too hard. But it wouldn't be any easier than doing
> assert(!isnan(x));
> 

That'd get real ugly, real quick.  Especially when you have complex lines of code that are using vectors of doubles with operator overloads.  Granted, the assert statement could go in the vector's operator overloads, but still the problem remains for complex lines of floating-point calculations...  Let me fabricate an example from a line of my code:

debug {
	assert(!isnan(a));
	assert(!isnan(b));
	assert(!isnan(c));
	assert(!isnan(d));
	assert(!isnan(e));
	assert(!isnan(f));
}
T = (a * b + c*d + (a * (e - b) + (e - c) * d) / f) * (1.0 / (a + d));

(the variable names have been changed to protect intellectual property and to disguise any actual meaning of the calculation)

Anyway, this is just one of a few hundred lines of calculations in the model, and requiring that block of 6 assert lines to be called before each line (worst-case scenario of course) is a bit overwhelming.  In reality, you'd only have to check the inputs as they come into the function with a nice contract - but to be honest, I never have used DbC and completely forget that they exist.

The way I see it, there are 2 possible solutions here:

1) Have compiler throw in assert(!isnan(x)) statements automatically under debug build (possibly with additional compiler switch) before each floating-point operation
2) Switch default QNaN initialization to SNaN and check FE_EXCEPT flag after each floating-point operation to throw a FloatingPointException (again under debug build possibly with additional compiler switch)

Are you sure that FE_EXCEPT flag is the only thing that happens when a SNaN is hit?  Isn't there a hardware interrupt tied in somewhere for this sort of thing?  Throwing up a flag is nice and all, but quite useless if it must be checked explicitly after each floating-point operation...

I think the implicit assert statement is a good option if the hardware end seems to fall apart.  It'd be no worse than implicit array bounds checking.  And like George said, it's only in debug mode.  It would certainly lighten the load from the programmer off to the compiler.

> 
>>Granted, if we use bad (non-D) libraries, then we're out of luck, but
>>the point here is to make it easy to write robust floating point
>>libraries in D. As well as robust applications.
>>
>>Somehow I can't help feeling this should be easier to implement than
>>bounds checking. Or then I've misunderstood something. :-)
> 
October 31, 2005
James Dunne wrote:
> 
> Are you sure that FE_EXCEPT flag is the only thing that happens when a SNaN is hit?  Isn't there a hardware interrupt tied in somewhere for this sort of thing?  Throwing up a flag is nice and all, but quite useless if it must be checked explicitly after each floating-point operation...

The C standard says that floating point exceptions should be handled in a similar fashion to exceptions raised by arithmetic exceptions, thus any traps the system supports should be called by feraiseexcept.  I know the Sun compiler can be set to behave this way, and I believe it can be turned off by specifying that quiet NaNs should be used (fuzzy on the details, I only saw mention of all this in their header files).  I'm not sure how much granularity might be useful, but it would probably no be terribly difficult to provide a mask that indicates which exceptions should throw/signal and which should not.  I'll check the IA-32 docs and see if I can find some more info on this.  My experience with floating point at this level is very limited.


Sean
October 31, 2005
It turns out that x86 does define a set of floating point exceptions, and these are handled just like divide by zero and such.  At a glance, I think exception handling support for this could be built into Phobos, likely by modifying internal/deh.c.  I need to read up a bit on structured exception handling, but I'll play with this a bit and see what I can work out.  I don't know offhand if it will conflict with how the DM C library handles floating point exceptions though, perhaps Walter can tell us?


Sean