Re: Why are structs and classes so different?

2022-05-15 Thread Walter Bright via Digitalmars-d-learn

On 5/15/2022 8:26 AM, Kevin Bailey wrote:

I'm trying to understand why it is this way.

Great question.

The difference, in a nutshell, is a struct is a value type, and a class is a 
reference type. This difference permeates every facet their behavior.


In C++, a struct can designed to be a value type or a reference type. But C++ 
does not recognize the difference, and so you can pass a reference type by 
value, which leads to all sorts of problems. You'll see C++ structs confused 
about what they are, as the designer didn't know the difference and would put a 
foot in both camps. A common example of this confusion is putting in virtual 
functions but neglecting to make the destructor virtual.


D draws a hard distinction between the two, making it both self-documenting, and 
heading off all sorts of errors from misusing one as the other.


A reference type is inherently a polymorphic type (i.e. virtual functions). 
Polymorphism via inheritance makes no sense for a value type.


Copy constructors make no sense for a polymorphic type, but are sensible for a 
value type.


And so on.

A strong distinction between value and reference types has turned out well for 
D. Naturally, some people still want a type to be both a floor wax and a dessert 
topping, but D is purposely going to make it difficult to do that.


P.S. Yes, you can pass a struct by reference with the `ref` keyword. That's not 
polymorphic behavior, though.


P.P.S. Yes, you can allocate a class instance on the stack rather than the GC by 
using the `scope` storage class. It will still be a reference type, but the 
compiler won't allow that reference to live longer than its stack frame. Java 
will automagically allocate classes on the stack if it can determine it cannot 
escape.


Re: DConf 2017 Videos

2020-04-25 Thread Walter Bright via Digitalmars-d-learn

On 4/25/2020 4:11 AM, Jacob Carlborg wrote:
I have previously downloaded the DConf videos. I sent them to Mike for him to 
upload.


Thank you! You have certainly saved the day here!



Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-08 Thread Walter Bright via Digitalmars-d-learn

On 4/8/2019 7:39 AM, Alex wrote:
My point is that you are going ape shit over using T.stringof, you posted no 


I mean, half the shit in __traits looks like it could be in std.traits and there 


Please tone down both the aggressiveness and the use of cuss words, and use 
professional demeanor.


Re: Address of data that is static, be it shared or tls or __gshared or immutable on o/s

2017-09-11 Thread Walter Bright via Digitalmars-d-learn

On 9/10/2017 2:38 PM, Cecil Ward wrote:
Ali, I have worked on operating systems' development in r+d. My definitions of 
terms are hopefully the same as yours. If we refer to two threads, if they both 
belong to the same process, then they share a common address space, by my 
definition of the terms 'thread' and 'process'. I use thread to mean basically a 
stack, plus register set, a cpu execution context, but has nothing to do with 
virtual memory spaces or o/s ownership of resources, the one exception being a 
tls space, which by definition is one-per-thread. A process is one or more 
threads plus an address space and a set of all the resources owned by the 
process according to the o/s. I'm just saying this so you know how I'm used to 
approving this.


Tls could I suppose either be dealt with by having allocated regions within a 
common address space that are all visible to one another. Objects inside a tls 
could (1) be referenced by absolute virtual addresses that are meaningful to all 
the threads in the process, but not meaningful to (threads belong to) other 
processes. (By definition of 'process'.) or (2) be referenced most often by 
section-offsets, relative addresses from the start of a tls section, which 
constantly have to be made usable by having the tls base virtual address added 
to them before they can be dereferenced adding a big runtime cost and making tls 
very bad news. I have worked on a system like (2). But even in (2) an address of 
a type-2 tls object can still be converted to a readily usable absolute virtual 
address and used by any thread in the process with zero overhead. A third option 
though could be to use processor segmentation, so tls objects have to (3a) be 
dereferenced using a segment prefixed operation, and then it's impossible to 
just have a single dereference operation such as star without knowing whether to 
use the segment prefix or not. But if it is again possible to use forbidden or 
official knowledge to convert the segmented form into a process-wide meaningful 
straight address (as in 8086 20-bit addresses) then we could term this 3a 
addressing. If this is not possible because vm hardware translation is in use 
then I will term this 3b. In 3a I am going to assume that vm hardware is used 
merely to provide relocation, address offsetting, so the use of a segmentation 
prefix basically merely adds a per-thread fixed offset to the virtual address 
and if you could discover that offset then you don't need to bother with the 
segment prefix. In 3b, vm hardware maps virtual addresses to a set of per-tls 
pages using who-knows-what mechanism, anyway something that apps cannot just 
bypass using forbidden knowledge to generate a single process-wide virtual 
address. This means that 3b threads are probably breaking my definition of 
thread vs process, although they threads of one process do also have a common 
address space and they share resources.


I don't know what d's assumptions if any are. I have very briefly looked at some 
code generated by GDC and LDC for Linux x64. It seems to me that these are 3a 
systems, optimised strongly enough by the compilers to remove 3a inefficiency 
that they are nearly 1. But I must admit, I haven't looked into it properly, 
just noted a few things in passing and haven't written any test cases as I don't 
know d well enough yet. I haven't seen the code these compilers generate for 
Windows.


D tries very hard to use the exact same TLS method used by the local C or C++ 
compiler, so the same assumptions and methods apply. Only of the local C or C++ 
compiler does not support TLS does D provide its own implementation.


In the case of Windows and Linux (and others), TLS support is embedded into the 
standard linker, and D makes use of that.


If an address is taken to a TLS object, any relocations and adjustments are made 
at the time the pointer is generated, not when the pointer is dereferenced. 
Hence, the pointer may be passed from thread to thread, and will still point to 
the same object. There is only ONE pointer type in D. D does not support 
multiple pointer types, such as near/far, or pointers tagged with additional 
data saying how they should be dereferenced.


TLS data is all owned by the process. TLS is not a method for inter-process 
communication.


TLS code generation for D is the same as for C and C++.


Re: Variables with scoped destruction in closures

2016-10-16 Thread Walter Bright via Digitalmars-d-learn

On 10/14/2016 3:18 AM, Nordlöw wrote:

t_scope.d(23,6): Error: variable t_scope.below.s has scoped destruction, cannot
build closure


  https://github.com/dlang/dmd/blob/master/src/toir.d#L820

The problem is the closure is generated when it is expected that the delegate 
will survive past the end of the scope (it's the whole point of a closure). But 
with a destructor that runs at the end of the scope, it cannot survive, and so 
the user of the closure will be referring to a destroyed object.


There is a current PR to improve the closure decision so that fewer closures are 
necessary,


  https://github.com/dlang/dmd/pull/5972

I don't know if that will resolve the issue you're having.

(A smaller test case would be nice!)


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-31 Thread Walter Bright via Digitalmars-d-learn

On 3/16/2016 4:18 AM, Johan Engelen wrote:

   I've found discussions, but not an actual "recommended" solution for the
problem of "statement is not reachable" warnings in templates with early
returns, e.g.:
```
bool nobool(T...)() {
 foreach (i, U; T) {
 static if (is(U == bool)) {
 return false;
 }
 }
 return true;  // emits "Warning: statement is not reachable"
}



bool nobool(T...)() {
 bool result = true;
 foreach (i, U; T) {
 static if (is(U == bool)) {
 result = false;
 break;
 }
 else
 {
 ...
 }
 }
 return result;  // emits "Warning: statement is not reachable"
}

Note that the optimizer will remove the dead loads.


Re: Porting from D1 to D2

2015-06-30 Thread Walter Bright via Digitalmars-d-learn

On 6/28/2015 2:48 AM, ponce wrote:

I don't quite get what code could be generating that reference, since I don't
call format or toString on a Throwable.


You can grep the .obj files for the symbol.