Re: Why is `Appender._data` a pointer to its `Data`-store?

2020-10-16 Thread Paul Backus via Digitalmars-d-learn
On Saturday, 17 October 2020 at 00:06:31 UTC, Steven 
Schveighoffer wrote:


Appender is ref counted IIRC.

-Steve


It's not; it uses the GC.


Re: How convert String to Fixed wchar Array?

2020-10-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/16/20 8:23 PM, Marcone wrote:

How convert String to Fixed wchar Array?

import std;

void main(){
     string name = "Marvin";
     wchar[255] wtext = name.to!(wchar[]); // Can not convert.
     writeln(wtext);
}


void main()
{
string name = "Marvin";
wchar[255] wtext;
import std.range;

wchar[] buf = wtext[];
put(buf, name);
auto setLen = wtext.length - buf.length; // number of wchars set in 
wtext.

writeln(wtext[0 .. setLen]);
}

A little bit of explanation: wchar[] is an output range that can accept 
any form of text. When you use `put` on it, it writes to it, AND shrinks 
from the front to allow remembering where it was. So at the end, buf is 
pointing at what is *left* in the buffer.


There may be better ways to do this, but this way will avoid any extra 
GC allocation.


-Steve


How convert String to Fixed wchar Array?

2020-10-16 Thread Marcone via Digitalmars-d-learn

How convert String to Fixed wchar Array?

import std;

void main(){
string name = "Marvin";
wchar[255] wtext = name.to!(wchar[]); // Can not convert.
writeln(wtext);
}


Re: Why is `Appender._data` a pointer to its `Data`-store?

2020-10-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/16/20 5:40 PM, Per Nordlöw wrote:

Why is `Appender`'s store `Data` put directly as

     `private Data* _data;`

instead of

     `private Data _data;`

?

Removing the pointer indirection would give better locality.

If it's about optimizing for empty `Appender`s then a `Appender*` should 
be used in those cases instead.


Appender is ref counted IIRC.

-Steve


Re: why do i need an extern(C): here?

2020-10-16 Thread Ali Çehreli via Digitalmars-d-learn

On 10/16/20 4:12 PM, WhatMeWorry wrote:

> Isn't dlopen() for Linux

More like dlopen() is for Posix, which means it should be available on 
Windows as well.


However, as I've discovered, a D shared library cannot be loaded with 
dlopen() because the main program and the shared library would do their 
own garbage collection (presumably with separate GC states) without 
being aware of each other and this won't work. Runtime.loadLibrary() 
knows to do the right thing and both sides are aware of each other.


> and LoadLibrary() for Windows?

Yes, but I am talking about core.runtime.Runtime.loadLibrary, which 
should call appropriate functions depending on the operating system.


> Or are you
> running Windows

I run Windows with mild disgust :p only for work-related applications. 
Otherwise, it's all Linux.


Ali



Re: why do i need an extern(C): here?

2020-10-16 Thread WhatMeWorry via Digitalmars-d-learn

On Friday, 16 October 2020 at 15:14:03 UTC, Ali Çehreli wrote:

On 10/15/20 2:42 PM, Ali Çehreli wrote:

> I've recently done the same by calling dlopen() and dlsym()
> directly. Runtime.loadLibrary documentation says "If the
library
> contains a D runtime it will be integrated with the current
runtime."
> That would explain why my program seg-faults for my first
tester with
> the garbage collector signatures in the function call stack.

Replacing dlopen() with Runtime.loadLibrary() did solve the 
segfault issue for me.


Ali


Isn't dlopen() for Linux and LoadLibrary() for Windows?  Or are 
you running Windows Subsystem for Linus (WSL) or mingw?



Just to add to the above discussions (for future searchers). I 
also found a demangle() in std.demangle that I used in the 
example below.


alias addSevenFuncSignature = int function(int, int);

addSevenFuncSignature  addSeven;
writeln(addSeven.mangleof);
writeln(demangle(addSeven.mangleof));

_D9onlineapp4mainFZ8addSevenPFiiZi
int function(int, int)* onlineapp.main().addSeven



Re: How can I convert Hexadecimal to RGB Color and vice-versa?

2020-10-16 Thread Ali Çehreli via Digitalmars-d-learn

On 10/16/20 1:10 PM, Marcone wrote:

How can I convert Hexadecimal to RGB Color and vice-versa?


On 10/16/20 1:10 PM, Marcone wrote:

> How can I convert Hexadecimal to RGB Color and vice-versa?

Do you mean from a string like "#123456" to the values of red, green, 
and blue? I am having more fun with D than usual. So, I wrote the 
following without understanding your requirements. :)


I am sure this already exists in various libraries.

import std.exception;
import std.range;
import std.format;
import std.stdio;
import std.traits;

struct RGB {
  ubyte red;
  ubyte green;
  ubyte blue;

  this(const(char)[] s) {
enforce(s.length < 8, format!`Invalid RGB string: "%s"`(s));

if (s.front == '#') {
  s.popFront();
}

 uint value;
 s.formattedRead!"%x"(value);
 this(value);
  }

  this(T)(T value)
  if (isIntegral!T) {
enforce(value >= 0 && value < 0x100_,
format!"Invalid RGB value: %s (0x%,*?x)"(value, 2, '_', 
value));


ubyte popLowByte() {
  ubyte b = value & 0xff;
  value >>= 8;
  return b;
}

this.blue = popLowByte();
this.green = popLowByte();
this.red = popLowByte();

assert(value == 0);
  }

  string asHex() {
return format!"%02x%02x%02x"(red, green, blue);
  }
}

void main() {
  auto a = RGB("#a0a0a0");
  writeln(a);

  auto b = RGB(0x10ff20);
  writeln(b);
  writeln(b.asHex);
}

Ali


Why is `Appender._data` a pointer to its `Data`-store?

2020-10-16 Thread Per Nordlöw via Digitalmars-d-learn

Why is `Appender`'s store `Data` put directly as

`private Data* _data;`

instead of

`private Data _data;`

?

Removing the pointer indirection would give better locality.

If it's about optimizing for empty `Appender`s then a `Appender*` 
should be used in those cases instead.


Re: Forward referencing functions in D

2020-10-16 Thread wilcro via Digitalmars-d-learn

On Friday, 16 October 2020 at 19:55:53 UTC, wilcro wrote:
The web page "Programming in D for C Programmers" 
(https://dlang.org/articles/ctod.html#forwardfunc) states that 
forward declarations are neither required nor permitted, and 
that the following construct is allowable:


void myfunc()
{
forwardfunc();
}

void forwardfunc()
{
... //do stuff
}


However, the following code will cause a compiler error:

import std.stdio: writeln;

void main()
{

void myfunc() {

forwardfunc(); // onlineapp.d(8): Error: undefined 
identifier forwardfunc

}

void forwardfunc() {

writeln("foo");
}

myfunc();

}


Evidently, I am misunderstanding something very elemental here; 
thanks for any enlightenment regarding this.





Thanks for your insights, Ali and Steve -- very helpful.


Re: Forward referencing functions in D

2020-10-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/16/20 4:47 PM, wilcro wrote:



Thanks to all for your responses; as a related followup question, would 
there be any reason to avoid placing the majority of code for a program 
outside of the main function?


Inner functions have benefits:

1. They are only accessible inside the function. Which means you only 
have to worry about correctness while INSIDE that function.

2. inner functions have access to the outer function's stack frame.

Often, I use inner functions to factor out a common piece of code that I 
don't want to have to write multiple times in the same function.


-Steve


Re: Packing of Struct Fields

2020-10-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/16/20 4:44 PM, ag0aep6g wrote:

On 16.10.20 22:32, Per Nordlöw wrote:
Why is `T.sizeof` 12 instead of 8 when `U.sizeof` is 8 in the 
following example?


struct S
{
 int i;
 bool b;
}

struct T
{
 S s;
 char c;
}

struct U
{
 int i;
 bool b;
 char c;
}

?


S.sizeof: 4 bytes for the int + 1 byte for the bool + 3 bytes padding so 
that the int is aligned = 8 bytes.


T.sizeof: 8 bytes for the S + 1 byte for the char + 3 bytes padding so 
that the S is aligned = 12 bytes.


U.sizeof: 4 bytes for the int + 1 byte for the bool + 1 byte for the 
char + 2 bytes padding so that the int is aligned = 8 bytes.


To further explain this -- the padding is added so things like pointer 
arithmetic on an array work.


For example, if you have a T* t, and you say t += 1, you want it to go 
to the next T, not to a misaligned spot.


You can also override this with align keyword. But I don't recommended 
this unless you know what you are doing. Misaligned reads/writes are 
different on different architectures, but even if they work and don't 
crash your program, they are going to be slower.


https://dlang.org/spec/attribute.html#align

-Steve


Re: Forward referencing functions in D

2020-10-16 Thread Ali Çehreli via Digitalmars-d-learn

On 10/16/20 1:47 PM, wilcro wrote:

> would
> there be any reason to avoid placing the majority of code for a program
> outside of the main function?

Keeping scopes of symbols as small as possible is a general guideline in 
D and elsewhere but I wouldn't crowd my main() function with details of 
program logic either. (Aside: There is no global name scope in D; 
everything belongs to a module.)


One thing I love about D is that there are no strong principles like 
that. I code in a way that is comfortable and change things later on as 
a needs arise. :)


Ali



Re: Packing of Struct Fields

2020-10-16 Thread Ali Çehreli via Digitalmars-d-learn

On 10/16/20 1:32 PM, Per Nordlöw wrote:
Why is `T.sizeof` 12 instead of 8 when `U.sizeof` is 8 in the following 
example?


struct S
{
     int i;
     bool b;
}

struct T
{
     S s;
     char c;
}

struct U
{
     int i;
     bool b;
     char c;
}

?


I have a function that dumps member layout of structs, which someone may 
find useful:


  http://ddili.org/ders/d.en/memory.html#ix_memory..offsetof

It prints the following for these types:

=== Memory layout of 'S' (.sizeof: 8, .alignof: 4) ===
   0: int i
   4: bool b
   5: ... 3-byte PADDING
=== Memory layout of 'T' (.sizeof: 12, .alignof: 4) ===
   0: S s
   8: char c
   9: ... 3-byte PADDING
=== Memory layout of 'U' (.sizeof: 8, .alignof: 4) ===
   0: int i
   4: bool b
   5: char c
   6: ... 2-byte PADDING

Copied here:

struct S
{
int i;
bool b;
}

struct T
{
S s;
char c;
}

struct U
{
int i;
bool b;
char c;
}

void printObjectLayout(T)()
if (is (T == struct) || is (T == union)) {
import std.stdio;
import std.string;

writefln("=== Memory layout of '%s'" ~
 " (.sizeof: %s, .alignof: %s) ===",
 T.stringof, T.sizeof, T.alignof);

/* Prints a single line of layout information. */
void printLine(size_t offset, string info) {
writefln("%4s: %s", offset, info);
}

/* Prints padding information if padding is actually
 * observed. */
void maybePrintPaddingInfo(size_t expectedOffset,
   size_t actualOffset) {
if (expectedOffset < actualOffset) {
/* There is some padding because the actual offset
 * is beyond the expected one. */

const paddingSize = actualOffset - expectedOffset;

printLine(expectedOffset,
  format("... %s-byte PADDING",
 paddingSize));
}
}

/* This is the expected offset of the next member if there
 * were no padding bytes before that member. */
size_t noPaddingOffset = 0;

/* Note: __traits(allMembers) is a 'string' collection of
 * names of the members of a type. */
foreach (memberName; __traits(allMembers, T)) {
mixin (format("alias member = %s.%s;",
  T.stringof, memberName));

const offset = member.offsetof;
maybePrintPaddingInfo(noPaddingOffset, offset);

const typeName = typeof(member).stringof;
printLine(offset,
  format("%s %s", typeName, memberName));

noPaddingOffset = offset + member.sizeof;
}

maybePrintPaddingInfo(noPaddingOffset, T.sizeof);
}

void main() {
  printObjectLayout!S();
  printObjectLayout!T();
  printObjectLayout!U();
}

Ali



Re: Forward referencing functions in D

2020-10-16 Thread wilcro via Digitalmars-d-learn

On Friday, 16 October 2020 at 19:55:53 UTC, wilcro wrote:
The web page "Programming in D for C Programmers" 
(https://dlang.org/articles/ctod.html#forwardfunc) states that 
forward declarations are neither required nor permitted, and 
that the following construct is allowable:


void myfunc()
{
forwardfunc();
}

void forwardfunc()
{
... //do stuff
}


However, the following code will cause a compiler error:

import std.stdio: writeln;

void main()
{

void myfunc() {

forwardfunc(); // onlineapp.d(8): Error: undefined 
identifier forwardfunc

}

void forwardfunc() {

writeln("foo");
}

myfunc();

}


Evidently, I am misunderstanding something very elemental here; 
thanks for any enlightenment regarding this.




Thanks to all for your responses; as a related followup question, 
would there be any reason to avoid placing the majority of code 
for a program outside of the main function?


Re: Packing of Struct Fields

2020-10-16 Thread ag0aep6g via Digitalmars-d-learn

On 16.10.20 22:32, Per Nordlöw wrote:
Why is `T.sizeof` 12 instead of 8 when `U.sizeof` is 8 in the following 
example?


struct S
{
     int i;
     bool b;
}

struct T
{
     S s;
     char c;
}

struct U
{
     int i;
     bool b;
     char c;
}

?


S.sizeof: 4 bytes for the int + 1 byte for the bool + 3 bytes padding so 
that the int is aligned = 8 bytes.


T.sizeof: 8 bytes for the S + 1 byte for the char + 3 bytes padding so 
that the S is aligned = 12 bytes.


U.sizeof: 4 bytes for the int + 1 byte for the bool + 1 byte for the 
char + 2 bytes padding so that the int is aligned = 8 bytes.


Packing of Struct Fields

2020-10-16 Thread Per Nordlöw via Digitalmars-d-learn
Why is `T.sizeof` 12 instead of 8 when `U.sizeof` is 8 in the 
following example?


struct S
{
int i;
bool b;
}

struct T
{
S s;
char c;
}

struct U
{
int i;
bool b;
char c;
}

?


Re: Forward referencing functions in D

2020-10-16 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Oct 16, 2020 at 08:04:07PM +, Imperatorn via Digitalmars-d-learn 
wrote:
[...]
> I think it might be just because you havent defined the function yet
> at that point.

That's not correct; the following works:

module mymodule;

void func() {
forwardfunc();
}

void forwardfunc() {
}

However, this only applies in module scope. If they were declared inside
a function body, forwardfunc must be declared before func.


T

-- 
It is impossible to make anything foolproof because fools are so ingenious. -- 
Sammy


Re: Forward referencing functions in D

2020-10-16 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Oct 16, 2020 at 07:55:53PM +, wilcro via Digitalmars-d-learn wrote:
> The web page "Programming in D for C Programmers"
> (https://dlang.org/articles/ctod.html#forwardfunc) states that forward
> declarations are neither required nor permitted,
[...]
> However, the following code will cause a compiler error:
[...]
> void main()
> {
> 
> void myfunc() {
> 
> forwardfunc(); // onlineapp.d(8): Error: undefined identifier
> forwardfunc
> }
> 
> void forwardfunc() {
> 
> writeln("foo");
> }
[...]

This is because order-independence of declarations only applies to
module scope, not to function scope.  So the above would work if myfunc
and forwardfunc were moved outside of main().  But inside a function
body, you must declare everything before you use them.


T

-- 
Philosophy: how to make a career out of daydreaming.


How can I convert Hexadecimal to RGB Color and vice-versa?

2020-10-16 Thread Marcone via Digitalmars-d-learn

How can I convert Hexadecimal to RGB Color and vice-versa?


Re: Forward referencing functions in D

2020-10-16 Thread Imperatorn via Digitalmars-d-learn

On Friday, 16 October 2020 at 19:55:53 UTC, wilcro wrote:
The web page "Programming in D for C Programmers" 
(https://dlang.org/articles/ctod.html#forwardfunc) states that 
forward declarations are neither required nor permitted, and 
that the following construct is allowable:


void myfunc()
{
forwardfunc();
}

void forwardfunc()
{
... //do stuff
}


However, the following code will cause a compiler error:

import std.stdio: writeln;

void main()
{

void myfunc() {

forwardfunc(); // onlineapp.d(8): Error: undefined 
identifier forwardfunc

}

void forwardfunc() {

writeln("foo");
}

myfunc();

}


Evidently, I am misunderstanding something very elemental here; 
thanks for any enlightenment regarding this.


I think it might be just because you havent defined the function 
yet at that point.


Re: Forward referencing functions in D

2020-10-16 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 16 October 2020 at 19:55:53 UTC, wilcro wrote:
Evidently, I am misunderstanding something very elemental here; 
thanks for any enlightenment regarding this.


Inside a function things happen in order, top to bottom, 
including declarations (you can only access local variables after 
they are declared, and nested functions work like local 
variables).


In a declaration, order is less important.

For recursive nested functions it can sometimes help to put a 
declaration inside a function:


void main() {
  // order matters here, in function
   struct Holder {
   // order doesn't matter in here, in decl
}
  // order matters again since functions run in sequence
}


Forward referencing functions in D

2020-10-16 Thread wilcro via Digitalmars-d-learn
The web page "Programming in D for C Programmers" 
(https://dlang.org/articles/ctod.html#forwardfunc) states that 
forward declarations are neither required nor permitted, and that 
the following construct is allowable:


void myfunc()
{
forwardfunc();
}

void forwardfunc()
{
... //do stuff
}


However, the following code will cause a compiler error:

import std.stdio: writeln;

void main()
{

void myfunc() {

forwardfunc(); // onlineapp.d(8): Error: undefined 
identifier forwardfunc

}

void forwardfunc() {

writeln("foo");
}

myfunc();

}


Evidently, I am misunderstanding something very elemental here; 
thanks for any enlightenment regarding this.


Re: Struct field destructor not called when exception is thrown in the main struct destructor

2020-10-16 Thread Ali Çehreli via Digitalmars-d-learn

On 10/16/20 9:05 AM, Steven Schveighoffer wrote:

> The destruction of members is outside the destructor's purview. It can't
> turn the destruction off, so it should logically be considered part of
> an enclosing function.

Thank you. Makes sense.

Ali



Re: Struct field destructor not called when exception is thrown in the main struct destructor

2020-10-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/16/20 11:11 AM, Ali Çehreli wrote:

On 10/16/20 6:12 AM, tchaloupka wrote:

 > struct Foo {
 >  Bar bar;
 >  bool err;
 >
 >  ~this() {
 >  // scope(failure) destroy(bar); // < this fixes the Bar
 > destructor call
 >  enforce(!err, "Test err");

Well, that check means "cannot continue", which means the compiler stops 
executing the destruction code because it can't. (It would a serious bug 
if it continued execution in a state that the program knows to be invalid.)


The destruction of members is outside the destructor's purview. It can't 
turn the destruction off, so it should logically be considered part of 
an enclosing function.


Note that enforce is throwing an *Exception*, not an *Error*, it does 
not mean the program is in an invalid state. Throwing an Error, the 
compiler is allowed to not clean up after itself.


Imagine if throwing an Exception disabled RAII in any enclosing function 
scopes because it considered that an invalid state.


Conceptually, bar's destructor is called on that closing brace but we 
decided to abort mission earlier. Your calling destroy(bar) may or may 
not be wrong in case of 'err'. Only you know at that point.


If that is the case, a hand written destructor should turn off automatic 
destruction of members. Either the compiler handles member destruction 
or it doesn't.


-Steve


Re: Struct field destructor not called when exception is thrown in the main struct destructor

2020-10-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/16/20 9:12 AM, tchaloupka wrote:

So when the exception is thrown within Foo destructor (and it's bad on 
it's own but can easily happen as destructors aren't nothrow @nogc by 
default).


Is this behavior expected?


I would say it's a bug. The compiler is going to call the member 
destructor even if the hand-written destructor does it too. If the 
compiler wants to take responsibility for cleaning up members, it should 
take full responsibility. In fact, there is no way to instruct the 
compiler "I'm handling the destruction of this member", so I don't see 
why it should matter if you exit the function via exception it should be 
any different.


-Steve


Re: Struct field destructor not called when exception is thrown in the main struct destructor

2020-10-16 Thread Paul Backus via Digitalmars-d-learn

On Friday, 16 October 2020 at 15:19:51 UTC, Paul Backus wrote:

On Friday, 16 October 2020 at 13:12:04 UTC, tchaloupka wrote:
So when the exception is thrown within Foo destructor (and 
it's bad on it's own but can easily happen as destructors 
aren't nothrow @nogc by default).


Is this behavior expected?


This is a compiler/language bug. It was fixed in DMD 2.083.0, 
but the new behavior requires a -preview switch, since it has 
the potential to break code.


More information:

- https://dlang.org/changelog/2.083.0.html#reboot14246
- https://dlang.org/changelog/2.085.0.html#preview-flags


Oops, I misread the destructor as a constructor in the original 
post. Never mind!


Re: Struct field destructor not called when exception is thrown in the main struct destructor

2020-10-16 Thread Paul Backus via Digitalmars-d-learn

On Friday, 16 October 2020 at 13:12:04 UTC, tchaloupka wrote:
So when the exception is thrown within Foo destructor (and it's 
bad on it's own but can easily happen as destructors aren't 
nothrow @nogc by default).


Is this behavior expected?


This is a compiler/language bug. It was fixed in DMD 2.083.0, but 
the new behavior requires a -preview switch, since it has the 
potential to break code.


More information:

- https://dlang.org/changelog/2.083.0.html#reboot14246
- https://dlang.org/changelog/2.085.0.html#preview-flags


Re: why do i need an extern(C): here?

2020-10-16 Thread Ali Çehreli via Digitalmars-d-learn

On 10/15/20 2:42 PM, Ali Çehreli wrote:

> I've recently done the same by calling dlopen() and dlsym()
> directly. Runtime.loadLibrary documentation says "If the library
> contains a D runtime it will be integrated with the current runtime."
> That would explain why my program seg-faults for my first tester with
> the garbage collector signatures in the function call stack.

Replacing dlopen() with Runtime.loadLibrary() did solve the segfault 
issue for me.


Ali




Re: Struct field destructor not called when exception is thrown in the main struct destructor

2020-10-16 Thread Ali Çehreli via Digitalmars-d-learn

On 10/16/20 6:12 AM, tchaloupka wrote:

> struct Foo {
>  Bar bar;
>  bool err;
>
>  ~this() {
>  // scope(failure) destroy(bar); // < this fixes the Bar
> destructor call
>  enforce(!err, "Test err");

Well, that check means "cannot continue", which means the compiler stops 
executing the destruction code because it can't. (It would a serious bug 
if it continued execution in a state that the program knows to be invalid.)


>  }

Conceptually, bar's destructor is called on that closing brace but we 
decided to abort mission earlier. Your calling destroy(bar) may or may 
not be wrong in case of 'err'. Only you know at that point.


> Is this behavior expected?

Yes.

Ali



Re: universal alpha?

2020-10-16 Thread Paul Backus via Digitalmars-d-learn

On Friday, 16 October 2020 at 13:27:57 UTC, Imperatorn wrote:

https://forum.dlang.org/post/e5ghnv$2bns$1...@digitaldaemon.com

On Tuesday, 30 May 2006 at 04:29:51 UTC, BCS wrote:
Does anyone have a link to a definition of universal alpha as 
used in the DMD docs?


(see: http://www.digitalmars.com/d/lex.html#identifier)


For any other lonely souls looking for the Appendix D I've 
uploaded it here:

https://github.com/Imperatorn/ISO_IEC-9899_1999


You can also find a draft version of the C99 standard in HTML 
format here:


http://port70.net/~nsz/c/c99/n1256.html


universal alpha?

2020-10-16 Thread Imperatorn via Digitalmars-d-learn

https://forum.dlang.org/post/e5ghnv$2bns$1...@digitaldaemon.com

On Tuesday, 30 May 2006 at 04:29:51 UTC, BCS wrote:
Does anyone have a link to a definition of universal alpha as 
used in the DMD docs?


(see: http://www.digitalmars.com/d/lex.html#identifier)


For any other lonely souls looking for the Appendix D I've 
uploaded it here:

https://github.com/Imperatorn/ISO_IEC-9899_1999


Struct field destructor not called when exception is thrown in the main struct destructor

2020-10-16 Thread tchaloupka via Digitalmars-d-learn
Found a pretty nasty bug in vibe-d: 
https://github.com/vibe-d/vibe.d/issues/2484


And it's caused by this behavior.

```D
import std;

struct Foo {
Bar bar;
bool err;

~this() {
// scope(failure) destroy(bar); // < this fixes the Bar 
destructor call

enforce(!err, "Test err");
}
}

struct Bar {
static int refs;
~this() { refs--; }
}

void main()
{
{
Foo f;
Bar.refs = 1;
}
assert(Bar.refs == 0);

try () {
Foo f;
f.err = true;
Bar.refs = 1;
}();
catch (Exception ex) {}
assert(Bar.refs == 0);
}
```

So when the exception is thrown within Foo destructor (and it's 
bad on it's own but can easily happen as destructors aren't 
nothrow @nogc by default).


Is this behavior expected?


Re: Call method of object variable

2020-10-16 Thread Andrey via Digitalmars-d-learn

Thank you!


Re: Call method of object variable

2020-10-16 Thread Simen Kjærås via Digitalmars-d-learn

On Friday, 16 October 2020 at 08:12:59 UTC, Andrey wrote:

Hi,
I have got:

struct Qaz
{
wstring read() {return null;}
wstring hear() {return "";} }

void main()
{
// ...
static if(some_condition) alias method = Qaz.hear;
else alias method = Qaz.read;

// ...
Qaz qaz;

qaz.method(); // ???
}


How to call alias "method" on object "qaz"?


https://dlang.org/spec/traits.html#child

The resulting code would be:

__traits(child, qaz, method)(/*arguments go here*/);

--
  Simen


Call method of object variable

2020-10-16 Thread Andrey via Digitalmars-d-learn

Hi,
I have got:

struct Qaz
{
wstring read() {return null;}
wstring hear() {return "";} }

void main()
{
// ...
static if(some_condition) alias method = Qaz.hear;
else alias method = Qaz.read;

// ...
Qaz qaz;

qaz.method(); // ???
}


How to call alias "method" on object "qaz"?