Re: GDC generate wrong .exe ("not a valid win32 application")
On Thursday, 22 June 2017 at 05:57:59 UTC, bauss wrote: On Wednesday, 21 June 2017 at 15:55:27 UTC, David Nadlinger wrote: On Monday, 19 June 2017 at 14:08:56 UTC, Patric Dexheimer wrote: Fresh install of GDC. (tried with 32x ad 32_64x) Where did you get the GDC executable from? The GDC project doesn't currently offer any official builds that target Windows; the 6.3.0 builds from https://gdcproject.org/downloads in fact generate Linux binaries. — David I see Windows distributions below the Linux ones. They're used for cross-compiling.
Re: GDC generate wrong .exe ("not a valid win32 application")
On Wednesday, 21 June 2017 at 15:55:27 UTC, David Nadlinger wrote: On Monday, 19 June 2017 at 14:08:56 UTC, Patric Dexheimer wrote: Fresh install of GDC. (tried with 32x ad 32_64x) Where did you get the GDC executable from? The GDC project doesn't currently offer any official builds that target Windows; the 6.3.0 builds from https://gdcproject.org/downloads in fact generate Linux binaries. — David I see Windows distributions below the Linux ones.
Re: Read conditional function parameters during compile time using __traits
On 06/21/2017 09:39 PM, timvol wrote: size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 1 ) { return 10; // More complex calculated value } size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 2 ) { return 20; // More complex calculated value } size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 3 ) { return 30; // More complex calculated value } [...] But... how can I execute these functions? I mean, calling doCalcLength(1) function says "Variable ubFuncCode cannot be read at compile time". So my idea is to create an array during compile time using traits (e.g. __traits(allMembers)) and to check this later during runtime. For illustration purposes something like this: --> During compile time: void function()[ubyte] calcLengthArray; auto tr = __traits(allMembers, example); foreach ( string s; tr ) { calcLengthArray[__trait(get, s)] = s; } As far as I know, there's no way to get the ubFuncCode from the constraints. In order to figure out which values are valid, you have to try them all. Which is actually doable for a ubyte: size_t function()[ubyte] calcLengthArray; static this() { import std.meta: aliasSeqOf; import std.range: iota; foreach (ubFuncCode; aliasSeqOf!(iota(ubyte.max + 1))) { static if (is(typeof(&calcLength!ubFuncCode))) { calcLengthArray[ubFuncCode] = &calcLength!ubFuncCode; } } } Using a static constructor instead of direct initialization, because you can't initialize a static associative array directly. --> During runtime: size_t doCalcLength(ubyte ubFuncCode) { auto length = 0; if ( ubFuncCode in calcLengthArray ) { length = calcLengthArray[ubFuncCode]!(ubFuncCode)(); } return length; } If you can accept hard-coding the range of ubFuncCode values here (and if there are no holes), then you can generate a switch that calls the correct calcLength version: import std.meta: aliasSeqOf; import std.range: iota; enum min = 1; enum max = 3; sw: switch (ubFuncCode) { foreach (code; aliasSeqOf!(iota(min, max + 1))) { case code: length = calcLength!code(); break sw; } default: throw new Exception("unexpected ubFuncCode"); } Instead of hard-coding the range, you could also do the same here as above when filling calcLengthArray: loop over all ubyte values and figure out which ones are valid with a `static if`. I hope everyone knows what I want to do :). But... does anyone know how I can realize that? I don't want to use a switch/case structure because the calcLength() functions can be very complex and I've over 40 different function codes. So, I think the best approach is to use something similar to the one I described. I don't see how you're reducing the complexity here. You have the same code, just spread over 40 functions, plus the extra code to make it work. From what I see, I'd prefer the hand-written switch.
Re: Read conditional function parameters during compile time using __traits
On Wednesday, 21 June 2017 at 19:39:14 UTC, timvol wrote: Hi! I've a simple array of bytes I received using sockets. What I want to do is to calculate the target length of the message. So, I defined a calcLength() function for each function code (it's the first byte in my array). My problem is that I defined the calcLength() function using conditions so that each calcLength should be called depending on the respective function code, see below: module example; private { size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 1 ) { return 10; // More complex calculated value } size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 2 ) { return 20; // More complex calculated value } size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 3 ) { return 30; // More complex calculated value } } size_t doCalcLength(ubyte ubFuncCode) { return calcLength!(ubFuncCode)(); } int main() { doCalcLength(1); return 0; } But... how can I execute these functions? I mean, calling doCalcLength(1) function says "Variable ubFuncCode cannot be read at compile time". So my idea is to create an array during compile time using traits (e.g. __traits(allMembers)) and to check this later during runtime. For illustration purposes something like this: --> During compile time: void function()[ubyte] calcLengthArray; auto tr = __traits(allMembers, example); foreach ( string s; tr ) { calcLengthArray[__trait(get, s)] = s; } --> During runtime: size_t doCalcLength(ubyte ubFuncCode) { auto length = 0; if ( ubFuncCode in calcLengthArray ) { length = calcLengthArray[ubFuncCode]!(ubFuncCode)(); } return length; } I hope everyone knows what I want to do :). But... does anyone know how I can realize that? I don't want to use a switch/case structure because the calcLength() functions can be very complex and I've over 40 different function codes. So, I think the best approach is to use something similar to the one I described. Let us to look at your function: size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 1 ) { return 10; // More complex calculated value } This function accepts only one template parameter and no other parameters. Template parameter should be known at compile time. You can't pass a value read from socket, because you can read from socket only at runtime. It is what the error message says. You calls such function as follows: calcLength!1() calcLength!2() and so on. Your doCalcLength won't work for the same reason. You try to pass "ubFuncCode" known at runtime as a template parameter, you will get the same error. You can try to instantiate all calcLength overloads and save them in calcLengthArray at some index just like you already do, but without any template parameters. The call would look something like: length = calcLengthArray[ubFuncCode](); But it is simplier and shorter just to use a switch statement: switch (ubFuncCode) { case 1: Do what calcLength!1() would do break; case 2: Do what calcLength!2() would do break; default: break; }
Re: Using array slices with C-style fread() from file
On 06/21/2017 12:20 PM, uncorroded wrote: > So @trusted is me guaranteeing to the compiler that this > function is safe? Yes and you shouldn't lie. :) > Is there any way of auditing this code through > valgrind, etc. That's a good idea, which you can do yourself but I don't think you can be sure beyond the tests that you've ran. There can always be corner cases where the library you use may not be memory-safe. You have to trust... :) > invaluable resource in getting me started. Thank you! Makes me very happy to hear that. :) Ali
Re: Dealing with the interior pointers bug
On Wednesday, 21 June 2017 at 17:11:41 UTC, TheGag96 wrote: On Wednesday, 21 June 2017 at 15:42:22 UTC, Adam D. Ruppe wrote: This comes from the fact that D's GC is conservative - if it sees something that *might* be a pointer, it assumes it *is* a pointer and thus had better not get freed. So is the GC then simply made to be "better-safe-than-sorry" or is this a consequence of how the GC does things? Or rather, does the GC know the type of any references to its memory at all? I suppose I should really ask if there's a document other than druntime's source that describes how the GC really works under the hood haha. You may like reading http://olshansky.me/gc/runtime/dlang/2017/06/14/inside-d-gc.html
Read conditional function parameters during compile time using __traits
Hi! I've a simple array of bytes I received using sockets. What I want to do is to calculate the target length of the message. So, I defined a calcLength() function for each function code (it's the first byte in my array). My problem is that I defined the calcLength() function using conditions so that each calcLength should be called depending on the respective function code, see below: module example; private { size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 1 ) { return 10; // More complex calculated value } size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 2 ) { return 20; // More complex calculated value } size_t calcLength(ubyte ubFuncCode)() if ( ubFuncCode == 3 ) { return 30; // More complex calculated value } } size_t doCalcLength(ubyte ubFuncCode) { return calcLength!(ubFuncCode)(); } int main() { doCalcLength(1); return 0; } But... how can I execute these functions? I mean, calling doCalcLength(1) function says "Variable ubFuncCode cannot be read at compile time". So my idea is to create an array during compile time using traits (e.g. __traits(allMembers)) and to check this later during runtime. For illustration purposes something like this: --> During compile time: void function()[ubyte] calcLengthArray; auto tr = __traits(allMembers, example); foreach ( string s; tr ) { calcLengthArray[__trait(get, s)] = s; } --> During runtime: size_t doCalcLength(ubyte ubFuncCode) { auto length = 0; if ( ubFuncCode in calcLengthArray ) { length = calcLengthArray[ubFuncCode]!(ubFuncCode)(); } return length; } I hope everyone knows what I want to do :). But... does anyone know how I can realize that? I don't want to use a switch/case structure because the calcLength() functions can be very complex and I've over 40 different function codes. So, I think the best approach is to use something similar to the one I described.
Re: Dealing with the interior pointers bug
On 06/21/2017 07:23 PM, H. S. Teoh via Digitalmars-d-learn wrote: Being a systems programming language means you should be able to do things outside the type system (in @system code, of course, not in @safe code), including storing pointers as int values. Any C code that your D program interoperates with may also potentially do similar things. The GC doesn't scan the C heap. You didn't say that it does, but it might be understood that way. Because of this, the GC cannot simply assume that an int value isn't actually a pointer value in disguise, so if that int value happens to coincide with an address of an allocated memory block, the only sane thing it can do is to assume the worst and assume that the memory is still live (via that (assumed) reference). There are cases where the GC does assume that ints are not pointers. For example, an int[] on the GC heap won't be scanned for pointers. The GC is neither completely precise nor completely conservative.
Re: Using array slices with C-style fread() from file
On Wednesday, 21 June 2017 at 19:11:44 UTC, Ali Çehreli wrote: On 06/21/2017 12:06 PM, uncorroded wrote: > Is > there any way of making the function with @safe as well? I get the > errors "cannot call @system function 'core.stdc.stdio.fread,fopen,fclose'. @trusted is exactly for that. It can be called from @safe code: @trusted @nogc ubyte[n] rand_bytes(uint n)() { // ... } @safe auto foo() { return rand_bytes!3(); } Ali Thanks! So @trusted is me guaranteeing to the compiler that this function is safe? Is there any way of auditing this code through valgrind, etc. Also, thanks a lot for your book on D. It has been an invaluable resource in getting me started.
Re: Using array slices with C-style fread() from file
On 06/21/2017 12:06 PM, uncorroded wrote: > Is > there any way of making the function with @safe as well? I get the > errors "cannot call @system function 'core.stdc.stdio.fread,fopen,fclose'. @trusted is exactly for that. It can be called from @safe code: @trusted @nogc ubyte[n] rand_bytes(uint n)() { // ... } @safe auto foo() { return rand_bytes!3(); } Ali
Re: Using array slices with C-style fread() from file
On Wednesday, 21 June 2017 at 18:58:58 UTC, tetyys wrote: On Wednesday, 21 June 2017 at 18:49:01 UTC, uncorroded wrote: Is there a way of making this work with D slices? Can they be used as C-style pointers? What about this: @nogc ubyte[n] rand_bytes(uint n)() { import core.stdc.stdio; FILE *fp; fp = fopen("/dev/urandom", "r"); ubyte[n] buf; uint bread = 0; while (bread < n) { auto toread = n - bread; auto read = fread(buf[bread .. $].ptr, ubyte.sizeof, toread, fp); bread += read; } fclose(fp); return buf; } ? Thanks a lot! That works. Did not know about the .ptr for a slice. Is there any way of making the function with @safe as well? I get the errors "cannot call @system function 'core.stdc.stdio.fread,fopen,fclose'.
Re: Using array slices with C-style fread() from file
On Wednesday, 21 June 2017 at 18:58:58 UTC, tetyys wrote: On Wednesday, 21 June 2017 at 18:49:01 UTC, uncorroded wrote: Is there a way of making this work with D slices? Can they be used as C-style pointers? What about this Or simpler, while (left) left -= fread(buf[n-left .. $].ptr, ubyte.sizeof, left, fp);
Re: Using array slices with C-style fread() from file
- Fixed-length arrays are value types. You may not want to return them if n is very large. - Every array has the .ptr property that gives the pointer to the first element. - What can be helpful to you here is the fact that you can treat any memory as a slice: import core.stdc.stdlib; struct S { double d; } void main() { ubyte * p = cast(ubyte*)malloc(10); ubyte[] slice = p[0..10];// 10 is number of elements // Another example with a struct object: auto objectCount = 7; S * objects = cast(S*)malloc(objectCount * S.sizeof); auto S_slice = objects[0..objectCount]; } Of course, you must be careful with slice lifetimes in this case; you shouldn't use the slices after freeing the memory. Ali
Re: Using array slices with C-style fread() from file
On Wednesday, 21 June 2017 at 18:49:01 UTC, uncorroded wrote: Is there a way of making this work with D slices? Can they be used as C-style pointers? What about this: @nogc ubyte[n] rand_bytes(uint n)() { import core.stdc.stdio; FILE *fp; fp = fopen("/dev/urandom", "r"); ubyte[n] buf; uint bread = 0; while (bread < n) { auto toread = n - bread; auto read = fread(buf[bread .. $].ptr, ubyte.sizeof, toread, fp); bread += read; } fclose(fp); return buf; } ?
Using array slices with C-style fread() from file
Hi all, I am writing a program to read device /dev/urandom file to get some random bytes. I am trying to bypass D's GC as I know the length of the buffer needed. I tried using std.stdio.File and rawRead but File cannot be used with @nogc. So I used core.stdc.stdio and used traditional C style. My code is here - https://dpaste.dzfl.pl/36e1df4cb99b (Also at end of post). I am using fread instead of read because /dev/urandom can be accessed by other programs (From this post - http://insanecoding.blogspot.in/2014/05/a-good-idea-with-bad-usage-devurandom.html ). As you can see from code, I ended up doing pointer arithmetic. Is there a way of making this work with D slices? Can they be used as C-style pointers? My D function used for getting random bytes: @nogc ubyte[n] rand_bytes(uint n)() { import core.stdc.stdio; FILE *fp; fp = fopen("/dev/urandom", "r"); ubyte[n] buf; ubyte *bp = &buf[0]; uint bread = 0; while (bread < n) { auto toread = n - bread; auto read = fread(bp, ubyte.sizeof, toread, fp); bread += read; bp += read; } fclose(fp); return buf; }
Re: Dealing with the interior pointers bug
On Wed, Jun 21, 2017 at 05:11:41PM +, TheGag96 via Digitalmars-d-learn wrote: > On Wednesday, 21 June 2017 at 15:42:22 UTC, Adam D. Ruppe wrote: > > This comes from the fact that D's GC is conservative - if it sees > > something that *might* be a pointer, it assumes it *is* a pointer > > and thus had better not get freed. > > So is the GC then simply made to be "better-safe-than-sorry" or is > this a consequence of how the GC does things? Or rather, does the GC > know the type of any references to its memory at all? The reason the GC must be conservative is because (1) D is a systems programming language, and also because (2) D interfaces directly with C. Being a systems programming language means you should be able to do things outside the type system (in @system code, of course, not in @safe code), including storing pointers as int values. Any C code that your D program interoperates with may also potentially do similar things. Because of this, the GC cannot simply assume that an int value isn't actually a pointer value in disguise, so if that int value happens to coincide with an address of an allocated memory block, the only sane thing it can do is to assume the worst and assume that the memory is still live (via that (assumed) reference). It's not safe for the GC to assume that it's merely an int, because if it actually turns out to be a pointer, then you'll end up with a dangling pointer and the ensuing memory corruption, security holes, and so forth. But assuming that the value is a pointer is generally harmless -- the memory block just doesn't get freed right away, but if the int is mutated afterwards, eventually the GC will get around to cleaning it up. The only big problem is in 32-bit code, where because of the very limited space of pointer values, the chances of a random int value coinciding with a valid pointer value is somewhat high, so if you have a large allocated memory block, the chances of a random int being mistaken for a reference to the block is somewhat high, so you could potentially run out of memory due to large blocks not being freed when they could be. Fortunately, though, in 64-bit land the space of pointer values is generally so large that it's highly unlikely that a random int would look like a pointer, so this generally isn't a problem if you're using 64-bit, which is the case more and more now as vendors are slowly phasing out 32-bit support. T -- People tell me that I'm skeptical, but I don't believe them.
Re: Dealing with the interior pointers bug
On Wednesday, 21 June 2017 at 15:42:22 UTC, Adam D. Ruppe wrote: This comes from the fact that D's GC is conservative - if it sees something that *might* be a pointer, it assumes it *is* a pointer and thus had better not get freed. So is the GC then simply made to be "better-safe-than-sorry" or is this a consequence of how the GC does things? Or rather, does the GC know the type of any references to its memory at all? I suppose I should really ask if there's a document other than druntime's source that describes how the GC really works under the hood haha.
Re: libc dependency
On 2017-06-21 17:51, David Nadlinger wrote: This is not relevant for cross-compilation, as long as you have the libraries available. You can actually link a D Windows x64/MSVCRT executable from Linux today if you copy over the necessary libraries. The question is just how we can make this as easy as possible for users. Perhaps not when targeting Windows but when targeting Linux. Can you target a specific version of libc or do you need to use static linking? -- /Jacob Carlborg
Re: GDC generate wrong .exe ("not a valid win32 application")
On Monday, 19 June 2017 at 14:08:56 UTC, Patric Dexheimer wrote: Fresh install of GDC. (tried with 32x ad 32_64x) Where did you get the GDC executable from? The GDC project doesn't currently offer any official builds that target Windows; the 6.3.0 builds from https://gdcproject.org/downloads in fact generate Linux binaries. — David
Re: libc dependency
On Wednesday, 21 June 2017 at 06:58:43 UTC, Jacob Carlborg wrote: Musl (or similar) should be available as an alternative. That will make it easier to cross-compile as well. This is not relevant for cross-compilation, as long as you have the libraries available. You can actually link a D Windows x64/MSVCRT executable from Linux today if you copy over the necessary libraries. The question is just how we can make this as easy as possible for users. — David
Re: Dealing with the interior pointers bug
On Wednesday, 21 June 2017 at 15:34:15 UTC, TheGag96 wrote: Could it ever be fixed? Easiest: stick `-m64` in your build. While it is somewhat common in 32 bit, it is very rare in 64 bit. This comes from the fact that D's GC is conservative - if it sees something that *might* be a pointer, it assumes it *is* a pointer and thus had better not get freed. Of course, the bug here if you do hit it is a relatively benign one: it will be a memory leak. So you might be able to live with it. But ketmar and I have done some image work in 32 bit that has hit such problems before, since the image arrays can be kinda large. In those cases, tweaking the GC or using malloc and free on the larger arrays are both solutions. (or, again, recompiling in 64 bit mode for most people).
Dealing with the interior pointers bug
I saw this Tip of the Week a while ago (http://arsdnet.net/this-week-in-d/2017-mar-12.html) and was kind of perplexed at it. It seems like a crazy potential bug... How exactly is the GC implemented that causes this problem to crop up? Does the GC just blindly scan memory until it finds pointers to heap memory to mark as "don't delete"? Could it ever be fixed?
Re: Linking external *.lib files
On Saturday, 17 June 2017 at 00:37:18 UTC, Jolly James wrote: Unfortunately, the public DUB package requires to be linked with the libs from pkgBASE/lib. What do I have to add to pkgBASE's dub.json? Side-note: the lib/ should not be moved for portability reasons if this is possible My bad solution: "lflags": [ "-Llib\\" ], but this requires the lib folder to be part of pkgAPP, not pkgBASE where I would like to have it. Does anyone have an idea? Replace the lflags directive with this in the pkgBase dub.json: "libs": [ "$PACKAGE_DIR/libs/foo" ]
Re: Linking external *.lib files
On Wednesday, 21 June 2017 at 13:07:31 UTC, Jolly James wrote: *push* Have you asked on the Dub forum? http://forum.rejectedsoftware.com/groups/rejectedsoftware.dub/
Re: Linking external *.lib files
*push*
Re: implib.exe no output files
On Monday, 19 June 2017 at 23:11:29 UTC, Joel wrote: On Sunday, 18 June 2017 at 09:48:31 UTC, Ivan Kazmenko wrote: On Sunday, 18 June 2017 at 07:41:27 UTC, Joel wrote: I got the file here: http://ftp.digitalmars.com/bup.zip It works on other computers. I was trying to update to the latest DAllegro (https://github.com/SiegeLord/DAllegro5). Though, I used another computer for the lib files and still couldn't get the latest DAllegro5 working. The .bat files in https://github.com/SiegeLord/DAllegro5 work fine for me. Could you please be more specific about what exactly you are doing, and what went wrong? Keep in mind that you need Allegro binaries (e.g. from http://liballeg.org/download.html#windows) to use implib. Ivan Kazmenko. I have the dll's in the same directory where I run the create lib .bat file. It displays the normal stuff, but no lib files! I'm wondering if implib needs to be worked on. Sorry, that's still not specific enough. I've just tested this in a fresh directory: 1. Get https://github.com/SiegeLord/DAllegro5 2. Get https://github.com/liballeg/allegro5/releases/download/5.2.2.0/allegro-mingw-gcc6.2.0-x86-static-5.2.2.zip 3. Put, for example, allegro-5.2.dll from the archive to DAllegro5 directory. 4. Run create_import_libs.bat, here is the output: - ...>rem This batch file creates import dlls in the current folder and strips the version number ...>rem because OPTLINK sucks. Digital Mars Import Library Manager Version 7.6B1n Copyright (C) Digital Mars 2000. All Rights Reserved. Input is a Windows NT DLL file 'allegro-5.2.dll'. Output is a Windows NT import library. Digital Mars Import Library Creator complete. - 5. Now I got allegro.lib in the directory. Which of these steps fails for you, and how? Ivan Kazmenko.
Re: libc dependency
On 2017-06-20 21:59, David Nadlinger wrote: For Windows, we use the MS C runtime, though, and the legal situation around redistribution seems a bit unclear. Musl (or similar) should be available as an alternative. That will make it easier to cross-compile as well. But I guess MS C runtime is required for linking with other existing C libraries. -- /Jacob Carlborg
Re: libc dependency
On 2017-06-20 14:10, Steven Schveighoffer wrote: I remember they specifically did not want to depend on anything in the C library. I can only tell you what I read from the source code :) . I didn't know enough about these things back in the D1 and Tango days. -- /Jacob Carlborg