Re: pointer to object resolution

2018-05-11 Thread Alex via Digitalmars-d-learn
On Friday, 11 May 2018 at 15:24:08 UTC, Steven Schveighoffer 
wrote:

On 5/11/18 8:53 AM, Alex wrote:



This behaves differently, w.r.t. to an arbitrary method, like 
"operator". Why? Is there any workaround?


operators don't follow pointers.

Imagine if you had a struct that overloads "+" and then you 
wanted to use pointer arithmetic, but instead it called 
ptr.opBinary.


Ah!


The workaround is to dereference the pointer. e.g. 42 in *sptr;

-Steve


Thanks a lot!


Re: getOpt with shared

2018-05-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/11/18 2:49 PM, Jonathan M Davis wrote:

On Friday, May 11, 2018 14:31:17 Steven Schveighoffer via Digitalmars-d-
learn wrote:

On 5/11/18 1:25 PM, Danny Arends wrote:

Hey all,

I have been working on creating a multi-threaded application, so I have
a shared configuration object which hold several command line parameters
(which I fill using getopt).

The problem is that I get deprecation warnings when trying to set
numerical values:

/usr/include/dmd/phobos/std/getopt.d(895,36): Deprecation:
read-modify-write operations are not allowed for shared variables. Use
core.atomic.atomicOp!"+="(*receiver, 1) instead.

using getopt with a shared object and boolean values seems completely
broken:

/usr/include/dmd/phobos/std/getopt.d(895,34): Error: operation not
allowed on bool *receiver += 1
/usr/include/dmd/phobos/std/getopt.d(751,46): Error: template instance
`std.getopt.handleOption!(shared(bool)*)` error instantiating
/usr/include/dmd/phobos/std/getopt.d(435,15):6 recursive
instantiations from here: getoptImpl!(string, shared(string)*, string,
shared(string)*, string, shared(VSync)*, string, shared(ulong)*, string,
shared(bool)*, string, shared(Verbose)*)

Is getopt not supposed to be used with shared structs ?


No, just fill in a local copy, and then copy it to the shared location.

In the case where all you want is read-only access to the data, build it
once and then cast to immutable:

immutable Config config;

void main(string[] args)
{
 Config localConfig;
 getopt(...); // fill in localConfig
 // VERY IMPORTANT, only do this ONCE, and don't use it before this
line *(cast()&config) = localConfig;
}

It should now be accessible from all threads.

Normally, this is not encouraged (casting away immutable), but the
compiler gets that an immutable global is allowed to be initialized once
(in fact, you can do this without casting inside shared static
constructors).


Except that because this is done outside of a shared static constructor,
you're technically mutating immutable data. This _should_ work, but it is
violating the type system, and technically, the compiler is allowed to
assume that config is Config.init everywhere. In practice, I wouldn't expect
a problem, but because it's violating the type system, all bets are off.


It's not a problem. The compiler cannot assume the value is .init 
because it doesn't have access to the whole codebase to see if some 
static ctor has changed it. Effectively, you ARE changing it in a static 
ctor, but just after all the other static ctors have run.


Crucially noted as well: don't use this value inside a static ctor!

-Steve


Re: getOpt with shared

2018-05-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 11, 2018 14:31:17 Steven Schveighoffer via Digitalmars-d-
learn wrote:
> On 5/11/18 1:25 PM, Danny Arends wrote:
> > Hey all,
> >
> > I have been working on creating a multi-threaded application, so I have
> > a shared configuration object which hold several command line parameters
> > (which I fill using getopt).
> >
> > The problem is that I get deprecation warnings when trying to set
> > numerical values:
> >
> > /usr/include/dmd/phobos/std/getopt.d(895,36): Deprecation:
> > read-modify-write operations are not allowed for shared variables. Use
> > core.atomic.atomicOp!"+="(*receiver, 1) instead.
> >
> > using getopt with a shared object and boolean values seems completely
> > broken:
> >
> > /usr/include/dmd/phobos/std/getopt.d(895,34): Error: operation not
> > allowed on bool *receiver += 1
> > /usr/include/dmd/phobos/std/getopt.d(751,46): Error: template instance
> > `std.getopt.handleOption!(shared(bool)*)` error instantiating
> > /usr/include/dmd/phobos/std/getopt.d(435,15):6 recursive
> > instantiations from here: getoptImpl!(string, shared(string)*, string,
> > shared(string)*, string, shared(VSync)*, string, shared(ulong)*, string,
> > shared(bool)*, string, shared(Verbose)*)
> >
> > Is getopt not supposed to be used with shared structs ?
>
> No, just fill in a local copy, and then copy it to the shared location.
>
> In the case where all you want is read-only access to the data, build it
> once and then cast to immutable:
>
> immutable Config config;
>
> void main(string[] args)
> {
> Config localConfig;
> getopt(...); // fill in localConfig
> // VERY IMPORTANT, only do this ONCE, and don't use it before this
> line *(cast()&config) = localConfig;
> }
>
> It should now be accessible from all threads.
>
> Normally, this is not encouraged (casting away immutable), but the
> compiler gets that an immutable global is allowed to be initialized once
> (in fact, you can do this without casting inside shared static
> constructors).

Except that because this is done outside of a shared static constructor,
you're technically mutating immutable data. This _should_ work, but it is
violating the type system, and technically, the compiler is allowed to
assume that config is Config.init everywhere. In practice, I wouldn't expect
a problem, but because it's violating the type system, all bets are off.

- Jonathan M Davis



Re: getOpt with shared

2018-05-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/11/18 1:25 PM, Danny Arends wrote:

Hey all,

I have been working on creating a multi-threaded application, so I have 
a shared configuration object which hold several command line parameters 
(which I fill using getopt).


The problem is that I get deprecation warnings when trying to set 
numerical values:


/usr/include/dmd/phobos/std/getopt.d(895,36): Deprecation: 
read-modify-write operations are not allowed for shared variables. Use 
core.atomic.atomicOp!"+="(*receiver, 1) instead.


using getopt with a shared object and boolean values seems completely 
broken:


/usr/include/dmd/phobos/std/getopt.d(895,34): Error: operation not 
allowed on bool *receiver += 1
/usr/include/dmd/phobos/std/getopt.d(751,46): Error: template instance 
`std.getopt.handleOption!(shared(bool)*)` error instantiating
/usr/include/dmd/phobos/std/getopt.d(435,15):    6 recursive 
instantiations from here: getoptImpl!(string, shared(string)*, string, 
shared(string)*, string, shared(VSync)*, string, shared(ulong)*, string, 
shared(bool)*, string, shared(Verbose)*)


Is getopt not supposed to be used with shared structs ?



No, just fill in a local copy, and then copy it to the shared location.

In the case where all you want is read-only access to the data, build it 
once and then cast to immutable:


immutable Config config;

void main(string[] args)
{
   Config localConfig;
   getopt(...); // fill in localConfig
   // VERY IMPORTANT, only do this ONCE, and don't use it before this line
   *(cast()&config) = localConfig;
}

It should now be accessible from all threads.

Normally, this is not encouraged (casting away immutable), but the 
compiler gets that an immutable global is allowed to be initialized once 
(in fact, you can do this without casting inside shared static 
constructors).


-Steve


Re: getOpt with shared

2018-05-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 11, 2018 18:01:18 Danny Arends via Digitalmars-d-learn wrote:
> On Friday, 11 May 2018 at 17:49:17 UTC, Jonathan M Davis wrote:
> > On Friday, May 11, 2018 17:25:44 Danny Arends via
> >
> > Digitalmars-d-learn wrote:
> >> [...]
> >
> > getopt is designed to be single-threaded. The keyword shared is
> > not used a single type in that module. If you want to use
> > shared with anything in D, you have three options:
> >
> > [...]
>
> Hey Jonathan,
>
> Thanks for the long and insightful answer.
> The object is indeed constructed from the main thread, but
> afterwards multiple threads need to read the values given via the
> command line. since everything in the object is read only I was
> hoping to get away with making it shared.
>
> I should just define tls variables to use with getopt and then
> set the corresponding variables in the shared object.

If you want to operate on that data as shared, then yes. But if you're
really just looking for each thread to have its own copy, I'd suggest that
you either give each thread its own copy on thread creation or pass it using
std.concurrency rather than trying to deal with a shared variable -
especially since the type system has no way to know that you're just
planning to read from the shared variable after that, and it will scream at
you for various operations - and once shared is fully locked down, it will
probably scream if you do much of _anything_ with shared, since at that
point, the compiler would only allow operations that were either marked with
shared or where it could guarantee that they were thread-safe.

- Jonathan M Davis



Re: getOpt with shared

2018-05-11 Thread Danny Arends via Digitalmars-d-learn

On Friday, 11 May 2018 at 17:49:17 UTC, Jonathan M Davis wrote:
On Friday, May 11, 2018 17:25:44 Danny Arends via 
Digitalmars-d-learn wrote:

[...]


getopt is designed to be single-threaded. The keyword shared is 
not used a single type in that module. If you want to use 
shared with anything in D, you have three options:


[...]


Hey Jonathan,

Thanks for the long and insightful answer.
The object is indeed constructed from the main thread, but 
afterwards multiple threads need to read the values given via the 
command line. since everything in the object is read only I was 
hoping to get away with making it shared.


I should just define tls variables to use with getopt and then 
set the corresponding variables in the shared object.


Danny


Re: getOpt with shared

2018-05-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 11, 2018 17:25:44 Danny Arends via Digitalmars-d-learn wrote:
> Hey all,
>
> I have been working on creating a multi-threaded application, so
> I have a shared configuration object which hold several command
> line parameters (which I fill using getopt).
>
> The problem is that I get deprecation warnings when trying to set
> numerical values:
>
> /usr/include/dmd/phobos/std/getopt.d(895,36): Deprecation:
> read-modify-write operations are not allowed for shared
> variables. Use core.atomic.atomicOp!"+="(*receiver, 1) instead.
>
> using getopt with a shared object and boolean values seems
> completely broken:
>
> /usr/include/dmd/phobos/std/getopt.d(895,34): Error: operation
> not allowed on bool *receiver += 1
> /usr/include/dmd/phobos/std/getopt.d(751,46): Error: template
> instance `std.getopt.handleOption!(shared(bool)*)` error
> instantiating
> /usr/include/dmd/phobos/std/getopt.d(435,15):6 recursive
> instantiations from here: getoptImpl!(string, shared(string)*,
> string, shared(string)*, string, shared(VSync)*, string,
> shared(ulong)*, string, shared(bool)*, string, shared(Verbose)*)
>
> Is getopt not supposed to be used with shared structs ?

getopt is designed to be single-threaded. The keyword shared is not used a
single type in that module. If you want to use shared with anything in D,
you have three options:

1. Use core.atomic to atomically do stuff like increment a integer.

2. Use a mutex (or synchronized block) to protect access to a shared object.
You lock the mutex before accessing the object (and before _all_ accesses to
that object). Within that section of code, you cast away shared and operate
on the object as thread-local. Then at the end of that section, before
releasing the lock, you make sure that no thread-local references to the
shared object remain, and then free the lock. e.g. something like

synchronized(mutex)
{
auto tls = cast(MyObject)mySharedObject.

//... do stuff...

} // at this point, no thread-local references to mySharedObject
  // should // exist

In this scenario, the types in question are not designed to be used with
shared at all. They're designed to be thread-local. So, if they're marked as
shared, they're basically useless except when you protect them with a mutex
and correctly cast away shared in order to operate on the object while it's
protected by the mutex and therefore is thread-safe.

3. An object is designed to be used as shared. In this case, it can have
shared member functions, and they can be called on shared objects, but then
internally, the object has to deal with properly managing shared. It either
uses atomics and/or uses mutexes as in #2 - it's just that in this case,
it's done internally by the object rather than the programmer using the
object.

synchronized classes are supposed to help with this particular case, but
unfortunately, they're not fully implemented, so they don't currently help.
But either way, the concept is still the same. You have on object that is
designed to work with shared and deals with all of the appropriate
protections internally.

So, those are your three options. In the case of getopt, if you want to use
shared, you basically have to use #2. It's not dealing with a basic type
like an int or pointer, so atomics aren't going to work, and it's not
designed to work with shared. So, if you want to do anything with getopt and
shared, you're going to have to protect it with a mutex.

That being said, I have to say that getopt seems like a really weird choice
for wanting to do anything with shared. You normally call it immediately at
the beginning of the program before doing anything with threads. The results
might then be passed on to other threads via std.concurrency or through
shared variables, but I wouldn't think that it would make a lot of sense to
try and used getopt from more than one thread.

- Jonathan M Davis



Re: getOpt with shared

2018-05-11 Thread Danny Arends via Digitalmars-d-learn

On Friday, 11 May 2018 at 17:25:44 UTC, Danny Arends wrote:

Hey all,

I have been working on creating a multi-threaded application, 
so I have a shared configuration object which hold several 
command line parameters (which I fill using getopt).


The problem is that I get deprecation warnings when trying to 
set numerical values:


/usr/include/dmd/phobos/std/getopt.d(895,36): Deprecation: 
read-modify-write operations are not allowed for shared 
variables. Use core.atomic.atomicOp!"+="(*receiver, 1) instead.


using getopt with a shared object and boolean values seems 
completely broken:


/usr/include/dmd/phobos/std/getopt.d(895,34): Error: operation 
not allowed on bool *receiver += 1
/usr/include/dmd/phobos/std/getopt.d(751,46): Error: template 
instance `std.getopt.handleOption!(shared(bool)*)` error 
instantiating
/usr/include/dmd/phobos/std/getopt.d(435,15):6 
recursive instantiations from here: getoptImpl!(string, 
shared(string)*, string, shared(string)*, string, 
shared(VSync)*, string, shared(ulong)*, string, shared(bool)*, 
string, shared(Verbose)*)


Is getopt not supposed to be used with shared structs ?


small example:

import std.getopt : getopt;

struct Settings {
  size_t myvalue = 0;
}

shared(Settings) config;

int main(string[] args) {
  getopt(args, "m|myvalue", &(config.myvalue));
  return(0);
}

Changing size_t to bool, results in the compilation error 
mentioned in the previous post


getOpt with shared

2018-05-11 Thread Danny Arends via Digitalmars-d-learn

Hey all,

I have been working on creating a multi-threaded application, so 
I have a shared configuration object which hold several command 
line parameters (which I fill using getopt).


The problem is that I get deprecation warnings when trying to set 
numerical values:


/usr/include/dmd/phobos/std/getopt.d(895,36): Deprecation: 
read-modify-write operations are not allowed for shared 
variables. Use core.atomic.atomicOp!"+="(*receiver, 1) instead.


using getopt with a shared object and boolean values seems 
completely broken:


/usr/include/dmd/phobos/std/getopt.d(895,34): Error: operation 
not allowed on bool *receiver += 1
/usr/include/dmd/phobos/std/getopt.d(751,46): Error: template 
instance `std.getopt.handleOption!(shared(bool)*)` error 
instantiating
/usr/include/dmd/phobos/std/getopt.d(435,15):6 recursive 
instantiations from here: getoptImpl!(string, shared(string)*, 
string, shared(string)*, string, shared(VSync)*, string, 
shared(ulong)*, string, shared(bool)*, string, shared(Verbose)*)


Is getopt not supposed to be used with shared structs ?



Re: pointer to object resolution

2018-05-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/11/18 8:53 AM, Alex wrote:



This behaves differently, w.r.t. to an arbitrary method, like 
"operator". Why? Is there any workaround?


operators don't follow pointers.

Imagine if you had a struct that overloads "+" and then you wanted to 
use pointer arithmetic, but instead it called ptr.opBinary.


The workaround is to dereference the pointer. e.g. 42 in *sptr;

-Steve


Re: Why are deprecated aliases considered equal for resolution?

2018-05-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 11, 2018 14:02:22 Nicholas Wilson via Digitalmars-d-learn 
wrote:
> -
> module a;
>
> struct foo {}
>
> deprecated alias bar = foo;
>
> --
> module b;
> struct bar {};
>
>
> ---
> module c;
>
> import a;
> import b;
>
> void baz(bar b) {}
>
> Error: `a.bar` at source/a.d(5,1) conflicts with `b.bar` at
> .b.d(2,1)
>
> I would have thought the undeprecated alias would have been used.

As I understand it, the only effect that deprecated really has is that you
get a message printed telling you that the symbol is deprecated if it's used
in undeprecated code. And that being the case, it definitely wouldn't affect
something like overload resolution.

And if you think about it, making deprecated affecting things like overload
resolution could get pretty risky. Remember that the whole idea here is that
a symbol is deprecated so that folks will stop using it, but you don't want
code to break because of it. If anything behaves differently, then it risks
code breakage, and that's exactly what you were trying to avoid by
deprecating the symbol rather than just removing it.

So, in general, when something is deprecated, we get to continue to live
with the negatives of having it around - it's just that it discourages its
use in new code and encourages people to stop using that symbol. So, when
the symbol is removed, the only code that breaks should be unmaintained code
that wasn't updated appropriately. But in the interim, it's still there
causing symbol conflicts and whatnot, and I don't see how it could be
otherwise without risking code breakage simply due to deprecation, and we
really don't want that. It's disruptive enough as it is just to tell folks
to stop using a symbol even if nothing breaks as long as the symbol is still
around.

- Jonathan M Davis



Why are deprecated aliases considered equal for resolution?

2018-05-11 Thread Nicholas Wilson via Digitalmars-d-learn

-
module a;

struct foo {}

deprecated alias bar = foo;

--
module b;
struct bar {};


---
module c;

import a;
import b;

void baz(bar b) {}

Error: `a.bar` at source/a.d(5,1) conflicts with `b.bar` at 
.b.d(2,1)


I would have thought the undeprecated alias would have been used.


Re: msgpack link failure - non-transitive pragma(lib)?

2018-05-11 Thread TED_996 via Digitalmars-d-learn

On Friday, 11 May 2018 at 12:53:08 UTC, Basile B. wrote:

On Friday, 11 May 2018 at 12:35:52 UTC, TED_996 wrote:

[...]


Yeah, right guess in the title ;)
you have to put the "pragma lib" again. Take the use of "pragma 
lib" in the binding as an information saying "you have to do 
this too".


Sorry for double posting, but I find what you wrote hard to 
believe, especially since DCD, which uses msgpack, has no 
pragma(lib "ws2_32") in it. Can you cite a source, please?


Re: msgpack link failure - non-transitive pragma(lib)?

2018-05-11 Thread TED_996 via Digitalmars-d-learn

On Friday, 11 May 2018 at 12:53:08 UTC, Basile B. wrote:

On Friday, 11 May 2018 at 12:35:52 UTC, TED_996 wrote:

[...]


Yeah, right guess in the title ;)
you have to put the "pragma lib" again. Take the use of "pragma 
lib" in the binding as an information saying "you have to do 
this too".


Okay, well, this information is nowhere to be seen (except 
*maybe* if you know where to look for). Besides, how am I 
supposed to know what every lib is using, including transitivity? 
There has to be a better way, right? A compiler warning? Maybe 
even a passing mention in the docs anywhere? (nowhere on this 
page, for example: https://dlang.org/spec/pragma.html, or on the 
msgpack page, or anywhere.)


pointer to object resolution

2018-05-11 Thread Alex via Digitalmars-d-learn

Hi all,
I'm sure, I didn't find something obvious, but:

Given this:

´´´
void main()
{
auto s = S();
s.operator;
assert(s.myOp(42));
assert(42 in s);

auto sptr = new S();
sptr.operator;
assert(sptr.myOp(42));
//assert(42 in sptr);  //<-- does not compile
}

struct S
{
void operator() const
{
assert(true);
}

bool opBinaryRight(string op)(size_t input) const if(op == "in")
{
return true;
}

bool myOp(size_t input)
{
return input in this;
}
}
´´´

The last line in the main does not compile with the message
source/app.d(9,9): Error: incompatible types for `(42) in 
(sptr)`: `int` and `S*`


This behaves differently, w.r.t. to an arbitrary method, like 
"operator". Why? Is there any workaround?


Re: msgpack link failure - non-transitive pragma(lib)?

2018-05-11 Thread Basile B. via Digitalmars-d-learn

On Friday, 11 May 2018 at 12:35:52 UTC, TED_996 wrote:
I've been trying to debug this for a long time now. I am trying 
to build one of the msgpack examples 
(examples/upacker_foreach.d) and the linking failed. I have 
since succeeded and I'm trying to find out if this is intended 
behavior or a bug in D (not msgpack, I think).


TL;DR: it seems to me like the pragma(lib, "ws2_32"); in 
core.sys.windows.winsock2, imported in msgpack.common, imported 
in msgpack (package.d), imported in my source files, does not 
hold; this was fixed when I added the pragma in my source file 
too.


Versions: Windows 10, dmd 2.080.0, dub 1.9.0

The dub build output:

Performing "debug" build using D:\D\dmd2\windows\bin\dmd.exe 
for x86.
msgpack-d 1.0.0-beta.6: target for configuration "library" is 
up to date.

hw ~master: building configuration "application"...
Linking...

OPTLINK (R) for Win32  Release 8.00.17
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
.dub\build\application-debug-windows-x86-dmd_2080-1E3111031ACEC4AEF53C62127331208A\hw.obj(hw)
 Error 42: Symbol Undefined _ntohl@4
.dub\build\application-debug-windows-x86-dmd_2080-1E3111031ACEC4AEF53C62127331208A\hw.obj(hw)
 Error 42: Symbol Undefined _ntohs@4
Error: linker exited with status 2
D:\D\dmd2\windows\bin\dmd.exe failed with exit code 1.

dub.json:

{
"name": "hw",
"authors": [
"ted_996"
],
"description": "A minimal D application.",
"copyright": "Copyright © 2018, ted_996",
"license": "proprietary",
"dependencies": {
"msgpack-d": ">=1.0.0-beta.6"
}
}

After some digging, I found that other binaries that used 
msgpack (DCD) were importing ws2_32, but it seemed like my 
binary was not. Both debug and release and x86 and x64 versions 
were failing to link; msgpack built fine but probably only the 
msgpack.lib file (no final link).


However, when I (counter-intuitively, for me) added pragma(lib, 
"ws2_32"); to my own source files, it built successfully. 
Should that have been necessary? it was not in any examples. 
What gives?


Thanks!


Yeah, right guess in the title ;)
you have to put the "pragma lib" again. Take the use of "pragma 
lib" in the binding as an information saying "you have to do this 
too".


msgpack link failure - non-transitive pragma(lib)?

2018-05-11 Thread TED_996 via Digitalmars-d-learn
I've been trying to debug this for a long time now. I am trying 
to build one of the msgpack examples (examples/upacker_foreach.d) 
and the linking failed. I have since succeeded and I'm trying to 
find out if this is intended behavior or a bug in D (not msgpack, 
I think).


TL;DR: it seems to me like the pragma(lib, "ws2_32"); in 
core.sys.windows.winsock2, imported in msgpack.common, imported 
in msgpack (package.d), imported in my source files, does not 
hold; this was fixed when I added the pragma in my source file 
too.


Versions: Windows 10, dmd 2.080.0, dub 1.9.0

The dub build output:

Performing "debug" build using D:\D\dmd2\windows\bin\dmd.exe for 
x86.
msgpack-d 1.0.0-beta.6: target for configuration "library" is up 
to date.

hw ~master: building configuration "application"...
Linking...

OPTLINK (R) for Win32  Release 8.00.17
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
.dub\build\application-debug-windows-x86-dmd_2080-1E3111031ACEC4AEF53C62127331208A\hw.obj(hw)
 Error 42: Symbol Undefined _ntohl@4
.dub\build\application-debug-windows-x86-dmd_2080-1E3111031ACEC4AEF53C62127331208A\hw.obj(hw)
 Error 42: Symbol Undefined _ntohs@4
Error: linker exited with status 2
D:\D\dmd2\windows\bin\dmd.exe failed with exit code 1.

dub.json:

{
"name": "hw",
"authors": [
"ted_996"
],
"description": "A minimal D application.",
"copyright": "Copyright © 2018, ted_996",
"license": "proprietary",
"dependencies": {
"msgpack-d": ">=1.0.0-beta.6"
}
}

After some digging, I found that other binaries that used msgpack 
(DCD) were importing ws2_32, but it seemed like my binary was 
not. Both debug and release and x86 and x64 versions were failing 
to link; msgpack built fine but probably only the msgpack.lib 
file (no final link).


However, when I (counter-intuitively, for me) added pragma(lib, 
"ws2_32"); to my own source files, it built successfully. Should 
that have been necessary? it was not in any examples. What gives?


Thanks!



Re: Extra .tupleof field in structs with disabled postblit blocks non-GC-allocation trait

2018-05-11 Thread Johan Engelen via Digitalmars-d-learn

On Thursday, 10 May 2018 at 19:14:39 UTC, Meta wrote:


So it looks like disabling a struct's postblit actually counts 
as having a __postblit and __xpostblit function (don't ask me 
why), in addition to a construction and opAssign... no idea 
why, and maybe this is a bug, but I bet there's a good reason 
for it.


https://issues.dlang.org/show_bug.cgi?id=18628

-Johan