Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-07 Thread evilrat via Digitalmars-d-learn

On Friday, 8 June 2018 at 00:55:35 UTC, cc wrote:


I've defined it in D, as per 
https://dlang.org/spec/cpp_interface.html#classes :




change this to class, or even abstract class as shown in example


extern(C++) {
interface CCallbackBase {
//this() { m_nCallbackFlags = 0; m_iCallback = 0; }
void Run( void *pvParam );
		void Run( void *pvParam, bool bIOFailure, SteamAPICall_t 
hSteamAPICall );

int GetICallback();
int GetCallbackSizeBytes();

		enum { k_ECallbackFlagsRegistered = 0x01, 
k_ECallbackFlagsGameServer = 0x02 }

//uint8 m_nCallbackFlags;
//int m_iCallback;
//friend class CCallbackMgr;

//CCallbackBase( const CCallbackBase& );
//CCallbackBase& operator=( const CCallbackBase& );
}
}


add extern(C++) to class as well to


class CImpl : CCallbackBase {
extern(C++) {
this() { m_nCallbackFlags = 0; m_iCallback = 0; }
void Run( void *pvParam ) { writeln("Run1"); }
		void Run( void *pvParam, bool bIOFailure, SteamAPICall_t 
hSteamAPICall ) { writeln("Run2"); }

int GetICallback() { return m_iCallback; }
		int GetCallbackSizeBytes() { return 
NumberOfCurrentPlayers_t.sizeof; } // ordinarily use templates 
to determine what type struct ptr to return

}
uint8 m_nCallbackFlags;
int m_iCallback;
}



you also may or may not need to mark non-virtual C++ methods as 
final.


Of course I haven't used D for quite some time so I can be 
mistaken.


But the lesson I learned the hard way is that in D for 
extern(C++) you don't use interface(it simply has no mapping to 
C++ types?), and for defining COM-interfaces use interface or it 
will bite you.

I hope it helps.



Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread H. S. Teoh via Digitalmars-d-learn
All this talk of CTFE and "compile-time", along with the confusion that
arises from conflating everything done by the compiler into the blanket
term "compile-time" makes me want to scream:

https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time



;-)

tl;dr: D's "compile-time" features consist of (at least) two distinct
phases of code transformation: template expansion and CTFE, and having a
proper understanding of exactly what they are and what the distinction
between them is, will go a long way in clearing up a lot of the
confusion commonly experienced by newcomers to D in regard to D's
so-called "compile-time" features.


--T


Is DWT busted?

2018-06-07 Thread TheGag96 via Digitalmars-d-learn
I'm sorry about bringing this into here instead of DWT's 
subforum, but it's somewhat dead and hasn't been getting a lot of 
attention. I decided to finally play around with DWT today and 
tried to build the example. I got this:


Performing "debug" build using /usr/bin/dmd for x86_64.
dwt:base 1.0.1+swt-3.4.1: target for configuration "library" is 
up to date.
dwt 1.0.1+swt-3.4.1: target for configuration "linux-gtk" is up 
to date.

main ~master: building configuration "application"...
Linking...
To force a rebuild of up-to-date targets, run again with --force.
Running ./main
Program exited with code -11

I'm on Pop!_OS (basically Ubuntu), x64, DMD 2.079.0. Every 
library they ask for is installed. I tried cloning the source and 
building their snippets, and none of them work. Other people have 
apparently had this same problem for the past few months, and 
none of them find a solution. What's going on here?


IDK if this is any help, but here's the backtrace according to 
gdb: https://pastebin.com/Xd46YwwP


Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread David Bennett via Digitalmars-d-learn

On Thursday, 7 June 2018 at 04:58:40 UTC, Jonathan M Davis wrote:


It would be trivial enough to create a wrapper template so that 
you can do something like


immutable n = ctfe!(foo());

e.g.

template ctfe(alias value)
{
enum ctfe = value;
}



Would this be equivalent to using static immutable?

static immutable n = foo();

In this case both the compiletime and runtime values were 
calculated using cfte.


Also back to the OP the way I think of enum, static types is like 
this:


alias and enum create compiletime stuff from compiletime stuff.
static creates runtime stuff from compiletime stuff.

Is that view valid in most cases?




Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread Mike Franklin via Digitalmars-d-learn

On Thursday, 7 June 2018 at 19:19:55 UTC, realhet wrote:

Hi,

The following narrow test program works fine when compiled with 
DMD to 32bit target:


import std.stdio, core.sys.windows.windows, core.runtime;
extern(Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
hPrevInstance, LPSTR lpCmdLine, int iCmdShow)

{
Runtime.initialize;
writeln("Hello");
stdout.flush; //exception
readln; //exception
return 0;
}

It shows the console window and waits for user input at readln.

If I try to compile this to 64bit target or with LDC (both 32 
and 64) it gets privileged instruction exception at 
stdout.flush. If I comment out flush then it fails at readln.


Is there a way to fix this? I don't wanna lose the console 
window even on 64bit.


Thanks!


You might be running into this issue:  
https://issues.dlang.org/show_bug.cgi?id=6880


I recall similar issues with a project I was working on, but I 
don't remember all the details now.  Anyway, I ended up with this 
in the end.


https://github.com/JinShil/Dsus2/blob/b08c66c6a6efb46134c409aac9f1c600d62f99fa/Dsus2/main.d#L300-L331

Mike


Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-07 Thread Mike Parker via Digitalmars-d-learn

On Friday, 8 June 2018 at 00:55:35 UTC, cc wrote:



class CImpl : CCallbackBase {
extern(C++) {


If anyone has any insight to provide it would be greatly 
appreciated, thanks!


I've not used any of the C++ interfacing features yet, but my 
understanding is the extern(C++) has to apply to the class 
declaration itself, not only the member functions:


extern(C++)
class CImpl : CCallbackBase {

Does that make a difference?


Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 7 June 2018 at 19:19:55 UTC, realhet wrote:

Hi,

The following narrow test program works fine when compiled with 
DMD to 32bit target:


import std.stdio, core.sys.windows.windows, core.runtime;
extern(Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
hPrevInstance, LPSTR lpCmdLine, int iCmdShow)

{
Runtime.initialize;
writeln("Hello");
stdout.flush; //exception
readln; //exception
return 0;
}

It shows the console window and waits for user input at readln.

If I try to compile this to 64bit target or with LDC (both 32 
and 64) it gets privileged instruction exception at 
stdout.flush. If I comment out flush then it fails at readln.


I get no exceptions with this code, but if I run if I compile 
with no flags, it prints hello and waits for input. With 
-m32mscoff or -m64, there's no output. If I run from Windows 
Explorer, the no-flag version pops up a console, prints and 
waits, while the -m32mscoff and do nothing.


As Steven mentioned earlier, this is a runtime issue. The 
standard I/O streams are not available in the MSVC runtime by 
default when compiling as a GUI application. You don't have to 
enable any flags to get that -- it's automatic when WinMain is 
present. The DititalMars runtime, which is what you get with the 
default compile, apparently does initialize the standard I/O 
streams and makes sure the console pops up when you write to it.




Is there a way to fix this? I don't wanna lose the console 
window even on 64bit.




If you want to keep WinMain and still have the console stuff 
available from the start with the MSVC runtime, you can get it 
with this:


dmd -m64 -L/SUBSYSTEM:console -L/ENTRY:WinMainCRTStartup foo.d

With this (for -m32mscoff as well), the above code runs the same 
as it does with the DigitalMars runtime.






Passing C++ class to DLL for callbacks from D (Steam)

2018-06-07 Thread cc via Digitalmars-d-learn
Hello, I'm attempting to interface with the Steam API DLL in D 
and running into some trouble working with callbacks.  I'm aware 
there's already a project here http://derelict-steamworks.dub.pm/ 
but it seems to have not yet addressed the same issue.  Steam 
provides ways to poll for whether an asynchronous request has 
completed yet and retrieve the results, but what I am trying to 
implement is receiving actual callbacks from the API.


Just for reference, I've gotten simple callbacks working in other 
APIs (passing a D function pointer to a C function and having it 
be called back), and the other basic Steam functions that don't 
deal with callbacks all work fine (defined in D as extern(C)).  
Here's where I'm running into trouble:


Definitions in C++ headers provided by Steam:

typedef uint64 SteamAPICall_t;
S_API void S_CALLTYPE SteamAPI_RegisterCallResult( class 
CCallbackBase *pCallback, SteamAPICall_t hAPICall );
S_API void S_CALLTYPE SteamAPI_UnregisterCallResult( class 
CCallbackBase *pCallback, SteamAPICall_t hAPICall );


class CCallbackBase
{
public:
CCallbackBase() { m_nCallbackFlags = 0; m_iCallback = 0; }
	// don't add a virtual destructor because we export this binary 
interface across dll's

virtual void Run( void *pvParam ) = 0;
	virtual void Run( void *pvParam, bool bIOFailure, SteamAPICall_t 
hSteamAPICall ) = 0;

int GetICallback() { return m_iCallback; }
virtual int GetCallbackSizeBytes() = 0;

protected:
	enum { k_ECallbackFlagsRegistered = 0x01, 
k_ECallbackFlagsGameServer = 0x02 };

uint8 m_nCallbackFlags;
int m_iCallback;
friend class CCallbackMgr;

private:
CCallbackBase( const CCallbackBase& );
CCallbackBase& operator=( const CCallbackBase& );
};


It's actually more complex than that as it has templated classes 
that inherit from that base so that there is a different template 
for each expected struct that gets returned from various async 
requests.  I'm trying to get the simplest possible scenario 
working first and hoping I'm not missing anything, but I don't 
actually understand how I'm supposed to work with the C++ objects 
enough really to be sure.  Here's how I've defined it in D, as 
per https://dlang.org/spec/cpp_interface.html#classes :


alias ulong SteamAPICall_t;
extern(C) {
	void SteamAPI_RegisterCallResult(CCallbackBase pCallback, 
SteamAPICall_t hAPICall);
	void SteamAPI_UnregisterCallResult(CCallbackBase pCallback, 
SteamAPICall_t hAPICall);

}

extern(C++) {
interface CCallbackBase {
//this() { m_nCallbackFlags = 0; m_iCallback = 0; }
void Run( void *pvParam );
		void Run( void *pvParam, bool bIOFailure, SteamAPICall_t 
hSteamAPICall );

int GetICallback();
int GetCallbackSizeBytes();

		enum { k_ECallbackFlagsRegistered = 0x01, 
k_ECallbackFlagsGameServer = 0x02 }

//uint8 m_nCallbackFlags;
//int m_iCallback;
//friend class CCallbackMgr;

//CCallbackBase( const CCallbackBase& );
//CCallbackBase& operator=( const CCallbackBase& );
}
}

class CImpl : CCallbackBase {
extern(C++) {
this() { m_nCallbackFlags = 0; m_iCallback = 0; }
void Run( void *pvParam ) { writeln("Run1"); }
		void Run( void *pvParam, bool bIOFailure, SteamAPICall_t 
hSteamAPICall ) { writeln("Run2"); }

int GetICallback() { return m_iCallback; }
		int GetCallbackSizeBytes() { return 
NumberOfCurrentPlayers_t.sizeof; } // ordinarily use templates to 
determine what type struct ptr to return

}
uint8 m_nCallbackFlags;
int m_iCallback;
}


Which then gets called later on as:

auto cbk = new CImpl();
cbk.m_iCallback = NumberOfCurrentPlayers_t.k_iCallback;
auto hid = 
SteamAPI_ISteamUserStats_GetNumberOfCurrentPlayers(...);

SteamAPI_RegisterCallResult(cbk, hid);

And then every frame SteamAPI_RunCallbacks(); runs, which is 
supposed to fire off the callbacks.  I've also tried using 
abstract class instead of interface.  My expectation of what's 
supposed to happen is that one of those Run() functions gets 
called at some point.  However, it never does (even though I can 
poll to determine the call has actually completed).  I'm hoping 
the problem is I'm simply not passing the right expected type of 
data to the registration function and/or haven't defined the 
interface in D properly (I admit I have very little idea how the 
C++ is working anymore, including what those private methods are 
for), and not an issue with utilizing the API itself, since I 
doubt there's anyone I could ask on the Steam end of things about 
interfacing with D.


My gut feeling is I'm doing something very incorrect/stupid on 
the definition end of things, I understand passing function 
pointers to C++ functions that intend to call back well enough 
but I'm confused about this concept of passing "class SomeClass 

Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread realhet via Digitalmars-d-learn
On Thursday, 7 June 2018 at 23:25:45 UTC, Steven Schveighoffer 
wrote:

...


The WinMain exported function works alone well and on 32bit it 
also does the console.
On 64 I also tried AllocConsole, but fail. I get the Console 
handle with GetConsoleHandle, it sends back a nonzero value.


But as I play with it, now I can broke it even when I only use 
main() as export.


This bat file runs(dmd and visual-d installed to default c:\d 
path) (It only affects LDC & win64)


echo void main(){ import std.stdio; writeln(123); } > test.d
ldmd2 -vcolumns -c -op -allinst -w -m64 -release -O -inline 
-boundscheck=off test.d

call msvcenv amd64
cd c:\d
link /LIBPATH:C:\d\ldc2\lib64 /OUT:test.exe /MACHINE:X64 /MAP 
legacy_stdio_definitions.lib test.obj druntime-ldc.lib 
phobos2-ldc.lib msvcrt.lib

test.exe


And when I want to run the same exe from outside with 
totalcommander, it brings up an "application was unable to start: 
0xc0fb exception in a small window o.O.


UPDATE: The exe only starts when "msvcenv.bat amd64" was called 
before. That enironment setter bat file is needed for the exe as 
well o.O


I really thank you for trying to help me. Maybe that other 
different runtime you mentioned is using environment variables to 
be able to start up. Tomorrow I will test it.


Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/7/18 7:16 PM, realhet wrote:

On Thursday, 7 June 2018 at 19:42:05 UTC, Steven Schveighoffer wrote:

Are you just compiling the 32-bit dmd version with default flags?
Yes, no flags at all and it defaults to a 32bit target. I can use the 
console and able to make windows, and able to setup an opengl window too.
The console (stdin/stdout/SetConsoleAttribute) stuff crashes only when I 
compile to 64bit with DMD or to 32/64 with LDC.


So that is definitely dmc initializing the console window in that context.



If so, it's likely an issue with MSVC runtime library not being 
properly set up. DMD 32 bit by default uses DMC runtime.

I just tried to put up msvcrt2017 runtime but doesnt solved the issue.


Sorry, I'm not familiar with Windows enough to help.



To verify, use the switch -m32mscoff to do 32-bit result but link 
against MSVC library.
Compiling this way is impossible: It can't link even basic stuff like 
GetDC().


Also lost with this one.




I know this isn't really an answer, but it at least narrows it
down. Been a while since I did windows development, but it sounds like 
you are trying to print to or read from a console that isn't open. A 
windows program that has gui-only flag doesn't by default allocate a 
console. Most likely dmc just does it for you.


To be honest I don't use gui-only flag as I don't even know about where 
to put it :D (.def file maybe, but I don't). I use 
core.Runtime.initialize only. That is enough in 32bit but not in 64bit.


I don't know what happens nowadays. I literally haven't tried to build 
non-console Windows applications since like 2008 or so? I thought it was 
a linker flag, but I'm not sure.


My goal is to have a fully functional exe that contains every necessary 
things inside it. So far this is given when I use DMD and compile to win32.
The error I'm getting is not a 'friendly' exception. It is a privileged 
instruction crash.


Well, you are telling the linker, when you create your WinMain function 
that you are handling all the runtime setup yourself, and you are not 
using a console. So somehow you have to initialize the console.


Alternatively, you can define extern(C) main function, and handle the D 
initialization from there.


Is there a reason you want the D runtime but don't want to have D 
initialize it for you?


And it caused only by adding the -m64 option, not changing anything 
else. The linking is done by DMD itself also. (If I link with 
msvcenv.bat && MSLink.exe, it produces also the same fail.)


Just to be clear, it's not the 32-bit vs 64-bit, it has to do with which 
C runtime you are using.


-Steve


Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread realhet via Digitalmars-d-learn
On Thursday, 7 June 2018 at 19:42:05 UTC, Steven Schveighoffer 
wrote:
Are you just compiling the 32-bit dmd version with default 
flags?
Yes, no flags at all and it defaults to a 32bit target. I can use 
the console and able to make windows, and able to setup an opengl 
window too.
The console (stdin/stdout/SetConsoleAttribute) stuff crashes only 
when I compile to 64bit with DMD or to 32/64 with LDC.


If so, it's likely an issue with MSVC runtime library not being 
properly set up. DMD 32 bit by default uses DMC runtime.
I just tried to put up msvcrt2017 runtime but doesnt solved the 
issue.


To verify, use the switch -m32mscoff to do 32-bit result but 
link against MSVC library.
Compiling this way is impossible: It can't link even basic stuff 
like GetDC().



I know this isn't really an answer, but it at least narrows it
down. Been a while since I did windows development, but it 
sounds like you are trying to print to or read from a console 
that isn't open. A windows program that has gui-only flag 
doesn't by default allocate a console. Most likely dmc just 
does it for you.


To be honest I don't use gui-only flag as I don't even know about 
where to put it :D (.def file maybe, but I don't). I use 
core.Runtime.initialize only. That is enough in 32bit but not in 
64bit.


My goal is to have a fully functional exe that contains every 
necessary things inside it. So far this is given when I use DMD 
and compile to win32.
The error I'm getting is not a 'friendly' exception. It is a 
privileged instruction crash.
And it caused only by adding the -m64 option, not changing 
anything else. The linking is done by DMD itself also. (If I link 
with msvcenv.bat && MSLink.exe, it produces also the same fail.)


Re: WTF! new in class is static?!?!

2018-06-07 Thread DigitalDesigns via Digitalmars-d-learn
On Thursday, 7 June 2018 at 23:08:22 UTC, Steven Schveighoffer 
wrote:

On 6/7/18 6:58 PM, DigitalDesigns wrote:
On Thursday, 7 June 2018 at 21:57:17 UTC, Steven Schveighoffer 
wrote:

On 6/7/18 5:07 PM, DigitalDesigns wrote:

class A;

class B
{
    A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


Yep, long-standing issue: 
https://issues.dlang.org/show_bug.cgi?id=2947


Almost a decade old!



wait! everyone is saying it is a feature! So, which is it, a 
feature or a bug?!?!?


It's a feature that you can assign a static initializer to a 
class or struct member and have that work at compile time 
(using CTFE).


But when it's a reference to mutable data, it's a bug. Just the 
idea that you have implicitly shared data if you create 
instances in multiple threads should make it obviously a bug.


Even back then it was a debate, look at the bug report. But 
it's definitely a bug. Just hard to close since it will 
probably break a lot of code.


-Steve


I would expect that using a static initialize would not break as 
much code going from immutable to mutable than the other way 
around. Someone should have been smart enough to create a static 
new so both methods could have been implemented in a sane way.


Re: WTF! new in class is static?!?!

2018-06-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/7/18 6:58 PM, DigitalDesigns wrote:

On Thursday, 7 June 2018 at 21:57:17 UTC, Steven Schveighoffer wrote:

On 6/7/18 5:07 PM, DigitalDesigns wrote:

class A;

class B
{
    A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


Yep, long-standing issue: https://issues.dlang.org/show_bug.cgi?id=2947

Almost a decade old!



wait! everyone is saying it is a feature! So, which is it, a feature or 
a bug?!?!?


It's a feature that you can assign a static initializer to a class or 
struct member and have that work at compile time (using CTFE).


But when it's a reference to mutable data, it's a bug. Just the idea 
that you have implicitly shared data if you create instances in multiple 
threads should make it obviously a bug.


Even back then it was a debate, look at the bug report. But it's 
definitely a bug. Just hard to close since it will probably break a lot 
of code.


-Steve


Re: WTF! new in class is static?!?!

2018-06-07 Thread DigitalDesigns via Digitalmars-d-learn
On Thursday, 7 June 2018 at 21:57:17 UTC, Steven Schveighoffer 
wrote:

On 6/7/18 5:07 PM, DigitalDesigns wrote:

class A;

class B
{
    A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


Yep, long-standing issue: 
https://issues.dlang.org/show_bug.cgi?id=2947


Almost a decade old!

-Steve


wait! everyone is saying it is a feature! So, which is it, a 
feature or a bug?!?!?


Re: WTF! new in class is static?!?!

2018-06-07 Thread aliak via Digitalmars-d-learn

On Thursday, 7 June 2018 at 21:32:54 UTC, Jonathan M Davis wrote:


struct S
{
int* ptr = new int(42);
}



Is that supposed to compile? -> https://run.dlang.io/is/SjUEOu

Error: cannot use non-constant CTFE pointer in an initializer 
&[42][0]


Re: WTF! new in class is static?!?!

2018-06-07 Thread ag0aep6g via Digitalmars-d-learn

On 06/07/2018 11:26 PM, Ethan wrote:
The spec isn't clear on this but it uses the same rules as struct field 
initialisation, ie it's defined once and copied to each instance on 
creation.


https://dlang.org/spec/struct.html#default_struct_init


It says there that "The default initializers may not contain references 
to mutable data."


DMD enforces that for pointers to primitives, but not for arrays, class 
objects, or even pointers to structs:



struct S
{
int* p = new int(1); /* Error: cannot use non-constant CTFE pointer 
in an initializer */

int[] a = [1, 2, 3]; /* no error */
C c = new C; /* no error */
S2* s = new S2; /* no error */
}

class C { int x = 4; }
struct S2 { int x = 5; }


Seems inconsistent to me.


Re: WTF! new in class is static?!?!

2018-06-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/7/18 5:07 PM, DigitalDesigns wrote:

class A;

class B
{
    A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


Yep, long-standing issue: https://issues.dlang.org/show_bug.cgi?id=2947

Almost a decade old!

-Steve


Re: WTF! new in class is static?!?!

2018-06-07 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 7 June 2018 at 21:07:26 UTC, DigitalDesigns wrote:
I'm glad I finally found this out! This is not typical behavior 
in most languages is it?



I don't think most languages allow this, and D used to not allow 
it either, but then CTFE got class support and it got enabled. If 
you understand how it works, it is sometimes useful...


But, it is confusing for a *lot* of people so it might make sense 
to ban it again - or at least make it more obvious that this is 
what you intended when you write it.


Re: WTF! new in class is static?!?!

2018-06-07 Thread Cym13 via Digitalmars-d-learn

On Thursday, 7 June 2018 at 21:07:26 UTC, DigitalDesigns wrote:

class A;

class B
{
   A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


I'm glad I finally found this out! This is not typical behavior 
in most languages is it?


I'd expect it to be translated to something like

class B
{
   A a;
   this()
   {
   a = new A();
   }
}

In C# it is different, can't remember if it is different in 
C++. This has caused bugs in my code because the fields are all 
pointing to the same data when I expected them to each have 
unique data ;/


This method is error prone and the behavior should be reversed, 
it should not break the majority of code. If one wants the 
current behavior then static new could be used or something 
else.


The spec looks pretty clear to me on that point 
https://dlang.org/spec/class.html#field-init


Besides, defining behaviour at construction is what constructors 
are for, I wouldn't expect anything outside a constructor to 
happen when an object is constructed. So while I understand that 
other languages may (successfully for them) do things differently 
I don't think I'd like a breaking change for that.


Re: WTF! new in class is static?!?!

2018-06-07 Thread Stefan Koch via Digitalmars-d-learn

On Thursday, 7 June 2018 at 21:07:26 UTC, DigitalDesigns wrote:

class A;

class B
{
   A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


I'm glad I finally found this out! This is not typical behavior 
in most languages is it?


I'd expect it to be translated to something like

class B
{
   A a;
   this()
   {
   a = new A();
   }
}

In C# it is different, can't remember if it is different in 
C++. This has caused bugs in my code because the fields are all 
pointing to the same data when I expected them to each have 
unique data ;/


This method is error prone and the behavior should be reversed, 
it should not break the majority of code. If one wants the 
current behavior then static new could be used or something 
else.


If you want a new one use a constructor call.
initalizers are support to be static, this only works because 
ctfe supports newing classes.




Re: WTF! new in class is static?!?!

2018-06-07 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, June 07, 2018 21:07:26 DigitalDesigns via Digitalmars-d-learn 
wrote:
> class A;
>
> class B
> {
> A a = new A();
> }
>
> auto b1 = new B();
> auto b2 = new B();
>
> assert(b1.a == b2.a)!!
>
>
> I'm glad I finally found this out! This is not typical behavior
> in most languages is it?
>
> I'd expect it to be translated to something like
>
> class B
> {
> A a;
> this()
> {
> a = new A();
> }
> }
>
> In C# it is different, can't remember if it is different in C++.
> This has caused bugs in my code because the fields are all
> pointing to the same data when I expected them to each have
> unique data ;/
>
> This method is error prone and the behavior should be reversed,
> it should not break the majority of code. If one wants the
> current behavior then static new could be used or something else.

Well, if that compiles now with a non-immutable class object, then that was
a language improvement.

In any case, yes, the class object would be shared across all instances of
the class.

_Every_ type in D has an init value that they get default-initialized to
before the constructor is run (assuming that the type even has a
constructor). In the case of both classes and structs, whatever the member
variables are directly initialized with make up the init value. So, if you
have something like

struct S
{
int i = 42;
}

then every instance of S will start with the value of 42 for i, and if you
have something like

struct S
{
int i = 42;

this(int j)
{
i = j;
}
}

then S.i is 42 before the constructor is run and will then be whatever it
gets assigned to in the constructor after the constructor has run.

The situation with classes is exactly the same as structs except that you
don't have direct access to the init value (since you only ever deal with
class references, not the classes themselves). One key result of this is
that the class object is fully initialized to its init value for its exact
type before _any_ constructors are called, so you don't get that problem
that C++ has where the object isn't fully its correct type until all of the
constructors have been called (so calling virtual functions from a class
constructor in D actually works, unlike C++).

All of this is quite clean with value types, but in the case of member
variables that are pointers, dynamic arrays, or reference types that would
mean that if you had something like

struct S
{
int* ptr = new int(42);
}

every instance of S would have the same exact value for S.ptr, which can be
surprising and is why it's sometimes been suggested that it not be legal to
directly initialize member variables with mutable, non-value types. However,
historically, this really only mattered for dynamic arrays, because
originally it wasn't legal to directly initialize any member variable that
was a pointer or reference, because the compiler and runtime weren't
sophisticated enough to handle it. Several years ago, it was made possible
to directly initialize immutable class references, but that doesn't really
cause any problems, since sharing an immutable object doesn't cause
problems. However, if it's now possible for the init value of an object to
contain a mutable class reference or pointer, then the problem does get
worse, and arguably, it becomes more critical to just make it illegal in the
case of member variables in order to avoid the surprises (and bugs) that
come when folks misunderstand what it really means to directly initialize a
member variable in D.

In any case, the way that D works here is a direct result of how init values
work, and it really doesn't make sense for it to work any other way. At
most, it would make sense to simply make it illegal to directly initialize
types where it would be a problem.

- Jonathan M Davis



Re: WTF! new in class is static?!?!

2018-06-07 Thread Ethan via Digitalmars-d-learn

On Thursday, 7 June 2018 at 21:07:26 UTC, DigitalDesigns wrote:

assert(b1.a == b2.a)!!


The spec isn't clear on this but it uses the same rules as struct 
field initialisation, ie it's defined once and copied to each 
instance on creation.


https://dlang.org/spec/struct.html#default_struct_init


Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, June 07, 2018 11:31:13 jmh530 via Digitalmars-d-learn wrote:
> On Wednesday, 6 June 2018 at 22:19:58 UTC, Jonathan M Davis wrote:
> > On Wednesday, June 06, 2018 18:18:16 jmh530 via
> >
> > Digitalmars-d-learn wrote:
> >> On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:
> >> > [snip]
> >> >
> >> > If you haven't yet, I'd suggest reading
> >>
> >> Would make a good blog series?
> >
> > What would make a good blog series? Something talking about
> > CTFE?
> >
> > - Jonathan M Davis
>
> I meant that stuff describing the nuances and motivations between
> static/enum/etc. Maybe more tutorial or something on the wiki
> than blog series? It's the type of thing that isn't obvious to
> someone new to D, but you explain very well. Better to save it in
> some place easy to find than let it get buried in Learn.

I probably should do more write-ups of stuff somewhere so that I can point
people to them, but for better or worse, I haven't done much of that. I've
mostly just answered questions here or at stackoverflow. I did finally get
my website set up though (http://jmdavisprog.com) so that I have somewhere
to post articles and whatnot, but I haven't done much with it yet. Sadly,
the only reason that I finally got around to setting it up was that I was
pretty much forced to in order to have a place to put the documentation for
dxml. Doing more useful write-ups has been on my todo list for ages but
mostly hasn't ended up as a priority with everything else on my plate -
which is arguably a bit dumb given how often I ultimately end up spending a
bunch of time answering questions on D.Learn even when I theoretically try
to not spend a lot of time replying to posts.

- Jonathan M Davis



WTF! new in class is static?!?!

2018-06-07 Thread DigitalDesigns via Digitalmars-d-learn

class A;

class B
{
   A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


I'm glad I finally found this out! This is not typical behavior 
in most languages is it?


I'd expect it to be translated to something like

class B
{
   A a;
   this()
   {
   a = new A();
   }
}

In C# it is different, can't remember if it is different in C++. 
This has caused bugs in my code because the fields are all 
pointing to the same data when I expected them to each have 
unique data ;/


This method is error prone and the behavior should be reversed, 
it should not break the majority of code. If one wants the 
current behavior then static new could be used or something else.





Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/7/18 3:19 PM, realhet wrote:

Hi,

The following narrow test program works fine when compiled with DMD to 
32bit target:


import std.stdio, core.sys.windows.windows, core.runtime;
extern(Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
hPrevInstance, LPSTR lpCmdLine, int iCmdShow)

{
 Runtime.initialize;
 writeln("Hello");
 stdout.flush; //exception
     readln; //exception
 return 0;
}

It shows the console window and waits for user input at readln.

If I try to compile this to 64bit target or with LDC (both 32 and 64) it 
gets privileged instruction exception at stdout.flush. If I comment out 
flush then it fails at readln.


Is there a way to fix this? I don't wanna lose the console window even 
on 64bit.


Thanks!



Are you just compiling the 32-bit dmd version with default flags?

If so, it's likely an issue with MSVC runtime library not being properly 
set up. DMD 32 bit by default uses DMC runtime.


To verify, use the switch -m32mscoff to do 32-bit result but link 
against MSVC library.


I know this isn't really an answer, but it at least narrows it down. 
Been a while since I did windows development, but it sounds like you are 
trying to print to or read from a console that isn't open. A windows 
program that has gui-only flag doesn't by default allocate a console. 
Most likely dmc just does it for you.


-Steve


Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-07 Thread realhet via Digitalmars-d-learn

Hi,

The following narrow test program works fine when compiled with 
DMD to 32bit target:


import std.stdio, core.sys.windows.windows, core.runtime;
extern(Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
hPrevInstance, LPSTR lpCmdLine, int iCmdShow)

{
Runtime.initialize;
writeln("Hello");
stdout.flush; //exception
readln; //exception
return 0;
}

It shows the console window and waits for user input at readln.

If I try to compile this to 64bit target or with LDC (both 32 and 
64) it gets privileged instruction exception at stdout.flush. If 
I comment out flush then it fails at readln.


Is there a way to fix this? I don't wanna lose the console window 
even on 64bit.


Thanks!



Re: Runtime introspection, or how to get class members at runtime Fin D

2018-06-07 Thread evilrat via Digitalmars-d-learn

On Thursday, 7 June 2018 at 12:32:26 UTC, Arafel wrote:

Thanks for all the answers!

Is it possible to register, say, a base class, and have all the 
subclasses then registered automatically?


My idea would be to make it as transparent as possible for the 
plugin implementation, and also not having to depend on it.


A.



I don't think so. It clearly states that children must mixin too, 
which can mean it just grabs symbols in scope only, and base 
class has no way of knowing about its subclasses. It also has 
"agressive mode" that will make metadata for all public 
symbols(?) it can walk, this may or may not be helpful depending 
on your requirements.


Besides there is no way(not that I am aware of) to make self 
registering stuff happen, you still need to call it somewhere. 
The most transparent option is probably just doing a mixin in 
each module that performs registration of all module symbols in 
module ctor.
The point is that there is absolute requirement to make explicit 
call for that, be it a module ctor mixin, class mixin or even 
user provided registration both at compile time or run time.
But since it is MIT licensed you can probably use the code as the 
starting point and adjust to your own needs.




BTW plug-ins is something that is right now possible on Linux(not 
sure about support on other *NIX systems), but in a very 
primitive form on Windows.
This is related to DLL support issues(such as type information 
not being passed across process/DLL boundaries), these issues 
also may include runtime issues as well such as inability to 
delegate the GC, which will mean there will be 2(or more) 
concurrent running GC's. But again I am not aware of the current 
situation.


Re: Why does using zlib without pragma(lib, ...) work?

2018-06-07 Thread rikki cattermole via Digitalmars-d-learn

On 08/06/2018 12:25 AM, tipdbmp wrote:

What other libraries (if any) are part of Phobos?



That is pretty much it.


Re: Runtime introspection, or how to get class members at runtime Fin D

2018-06-07 Thread Arafel via Digitalmars-d-learn

Thanks for all the answers!

Is it possible to register, say, a base class, and have all the 
subclasses then registered automatically?


My idea would be to make it as transparent as possible for the plugin 
implementation, and also not having to depend on it.


A.




There is a library that creates reflection metadata for you. [1]

It seems a bit outdated and has some not-that-obvious compilation 
errors(for example getting ctor and callling it with runtime known type, 
or some other non template stuff), but other than that seems to be 
working (note that I didn't thorougly tested it, but its unittests 
succeeds on DMD 2.080 for both Windows x86 mscoff & x64 )


[1] https://code.dlang.org/packages/witchcraft





Re: Why does using zlib without pragma(lib, ...) work?

2018-06-07 Thread tipdbmp via Digitalmars-d-learn

What other libraries (if any) are part of Phobos?



Re: Why does using zlib without pragma(lib, ...) work?

2018-06-07 Thread rikki cattermole via Digitalmars-d-learn

On 07/06/2018 11:47 PM, tipdbmp wrote:

The following compiles without pragma(lib, ...):

extern(C) {
     const(char)* zlibVersion();
}

void main() {
     const(char)* sz = zlibVersion();
}


It has already been compiled in as part of Phobos.



Why does using zlib without pragma(lib, ...) work?

2018-06-07 Thread tipdbmp via Digitalmars-d-learn

The following compiles without pragma(lib, ...):

extern(C) {
const(char)* zlibVersion();
}

void main() {
const(char)* sz = zlibVersion();
}



Re: Runtime introspection, or how to get class members at runtime Fin D

2018-06-07 Thread evilrat via Digitalmars-d-learn

On Wednesday, 6 June 2018 at 13:28:02 UTC, Arafel wrote:


I know it might not be the most idiomatic D, but as somebody 
with mostly a Java background (with some C and just a bit of 
C++) it seems something really straightforward to me: 
myObject.getClass().getFields() [2].


Also, I know I could add some UDA or even crawl the modules and 
have this information generated automatically at compilation 
time and added to the type itself in a member, and I might even 
end up doing it, but honestly, I think it's something that the 
language should provide in a kind of easy / accessible way.


Powerful as compile-time introspection is, I think runtime 
shouldn't be forgotten either :-)


Thanks,

A.

[1]: https://dlang.org/library/object/type_info__class.html
[2]: 
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getFields--


There is a library that creates reflection metadata for you. [1]

It seems a bit outdated and has some not-that-obvious compilation 
errors(for example getting ctor and callling it with runtime 
known type, or some other non template stuff), but other than 
that seems to be working (note that I didn't thorougly tested it, 
but its unittests succeeds on DMD 2.080 for both Windows x86 
mscoff & x64 )


[1] https://code.dlang.org/packages/witchcraft



Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread jmh530 via Digitalmars-d-learn

On Wednesday, 6 June 2018 at 22:19:58 UTC, Jonathan M Davis wrote:
On Wednesday, June 06, 2018 18:18:16 jmh530 via 
Digitalmars-d-learn wrote:

On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:
> [snip]
>
> If you haven't yet, I'd suggest reading

Would make a good blog series?


What would make a good blog series? Something talking about 
CTFE?


- Jonathan M Davis


I meant that stuff describing the nuances and motivations between 
static/enum/etc. Maybe more tutorial or something on the wiki 
than blog series? It's the type of thing that isn't obvious to 
someone new to D, but you explain very well. Better to save it in 
some place easy to find than let it get buried in Learn.