Re: Networking library
On Thursday, 15 March 2018 at 00:10:28 UTC, Cecil Ward wrote: On Thursday, 15 March 2018 at 00:06:49 UTC, Cecil Ward wrote: Can anyone point me in the direction of a library that provides very very lightweight (minimum overhead) asynchronous i/o routines for - shopping list [...] Actually I realise that if I could simply write a wrapper pretty easily, with suitable help, then C libraries could be included in the list of candidates, but only if I can get the necessary help in writing a D-toC & C-to-D safe wafer-thin wrapper layer. A pure D solution: https://github.com/ikod/dlang-requests (though I think it doesn't support everything on your list yet) Another pure D solution is Vibe.d - have a look at http://vibed.org/api/vibe.core.net/listenTCP While Phobos's high-level wrapper std.net.curl probably don't provide what you are looking for, the low-level curl might: https://dlang.org/phobos/etc_c_curl.html You would need to manually wrap the curl calls into an asynchronous handler though there are quite a few eventloop implementations on the dub registry.
Re: How do I make only the array itself immutable?
On Thursday, March 15, 2018 02:06:23 Marc via Digitalmars-d-learn wrote: > Can I make it work? > > >struct S > >{ > > > > int[] l; > > > >} > > then > > >auto s = S(); > >s.l ~= 1; // ok > >s.l = []; // error It's not possible to do anything like that, and it really doesn't make sense when you consider how dynamic arrays work. A dynamic array is essentially struct DynamicArray(T) { size_t length; T* ptr; } If you do const(T[]), then that would be like having struct DynamicArray { const size_t length; const(T*) ptr; } whereas if you have const(T)[], then that would be like struct DynamicArray { size_t length; const(T)* ptr; } Either way, in order to append to a dynamic array, the length must be mutated, and the ptr will potentially be mutated (that depends on whether the slice of memory that the dynamic array refers to has room to be appended to in place or whether a new buffer has to be allocated). So, to append to a dynamic array, the only thing that can be const or immutable is the data pointed to by the pointer. And to prevent assigning a new value to a dynamic array, the whole thing would have to be const or immutable. So, if you prevent assigning to a dynamic array, you also prevent appending to it. And for that matter, if you prevent appending to it, you prevent assigning to it. On some level, appending _is_ assigning. If you want to have a dynamic array which you can append to but can't explicitly assign a new value to, you'll have to wrap it in a struct with the appropriate operators overloaded and use that instead of using a dynamic array directly. But if the reason you want to prevent the assignment has anything to do with wanting to prevent the ptr from changing, then you'll pretty much have to give up on appending, because if the dynamic array's capacity isn't large enough to append to in place, it's going to allocate a new buffer and change the ptr value. - Jonathan M Davis
How do I make only the array itself immutable?
Can I make it work? struct S { int[] l; } then auto s = S(); s.l ~= 1; // ok s.l = []; // error
Re: Networking library
On Thursday, 15 March 2018 at 00:06:49 UTC, Cecil Ward wrote: Can anyone point me in the direction of a library that provides very very lightweight (minimum overhead) asynchronous i/o routines for - shopping list [...] Actually I realise that if I could simply write a wrapper pretty easily, with suitable help, then C libraries could be included in the list of candidates, but only if I can get the necessary help in writing a D-toC & C-to-D safe wafer-thin wrapper layer.
Re: CTFE and -betterC
On Wednesday, 14 March 2018 at 01:17:54 UTC, rikki cattermole wrote: You will still need DllMain, that is a platform requirement. I am not sure about that because when DllAnalyser don't see it in the opengl32.dll from the system32 directory. And the documentation indicate that it is optional. I finally choose to put the entry points generation in a sub-project that put them in a d file, like that it is easier to make the CTFE working and will be much better for the debugging and compilation time. So I have also some few other questions : - Is it a bug that ctRegex doesn't with the return of allMembers? - What is the status of the new CTFE engine? - Will CTFE be able to write files or expose a way to see to resulting generated code for a debug purpose? - Is there a reason why CTFE is impacted by the -betterC option?
Networking library
Can anyone point me in the direction of a library that provides very very lightweight (minimum overhead) asynchronous i/o routines for - shopping list 1. sending and receiving IPv4 / IPv6 packets, 2. sending receiving ICMP and 3, handling incoming outgoing TCP connections and 4. handling SCTP connections. Secondingly I am in the market for a library that handles the sending and receiving of straight ethernet packets. Also doing ARP / NDP too. Rules of the beauty contest: Some abstraction of asynchronous i/o with asynchronous events, but the main priority is being very very lean and low-level, with top time-performance. If it comes to a beauty contest, this judge I would prefer something C-style as I don't speak C++, have yet to drink the mindless class bullshit koolaid. Since my background is VAX/VMS asynchronous io an asynchronous model with optional callbacks as in VMS or Win NT events will win the beauty parade. Operating systems? Cross-o/s portability- unsure. Not interested in solutions that are synchronous-io-only and so require your code to be split up into multiple threads just to get around the problems caused by synchronous (‘blocking’ some call it) io calls. Requiring threads is a rule-out / show stopper unless I could easily hide such a thing, but that doesn't sound feasible. Any suggestions gratefully received.
Re: Function argument that is a pointer to memory which the function is not allowed to modify, as in C const
On 03/14/2018 11:23 PM, Cecil Ward wrote: say in C I have a function with a pointer argument foo( const sometype_t * p ) I have asked about this D nightmare before. Using the same pattern in D or the in argument qualifier as far as I can see the value of the pointer is then itself effectively locked made constant. Without dangerous and ugly casts you are stuck. q1. If you want a pointer to memory that is not to be modified then you can't walk the pointer through that memory. So what are my options? I need a pointer that I can increment. (I could avoid the whole issue by using an index instead, but that seems to be giving in to madness.) I think you're looking for this: `const(sometype_t)* p`. Here, the pointer itself is mutable. [...] q2. If you want a pointer to modifiable memory but wish to ensure that the value of that address stays fixed, stays where it's put, then what on earth do you do. What are my options? Can't be done directly with type qualifiers. You could maybe write a wrapper struct that acts like a pointer while disallowing modification of the pointer itself. I don't know how feasible this could be. I've never felt a need for it. [...] q3. The in keyword seems to be mixed up concerning the distinction between modifiable arguments and modifiable memory. Is there any way of making in usable for the purposes of documenting the calling convention, showin which arguments are inputs only, which are outputs and which are modified - read-modified-returned? `in` was meant to mean `scope const`. But I think it's effectively just `const` at the moment. Redefining `in` to something more useful probably means it has to be deprecated and removed first. Then brought back later with a new meaning. If that happens, it's going to take years. [...] q4. If my understanding is correct, it seems difficult to create a non const copy of (an address that is fixed) either; that is, making a modifiable copy of an address, one which can be incremented, moved upwards starting from a locked base address. You can easily make a mutable pointer from a const one: const int* c; const(int)* m = c; /* no problem */ The target of the pointer just has to remain `const`. [...] There probably is a tool somewhere to safely create a modifiable object based on a const object but I'm not sure where to look. Generally, that means a deep copy, right? I don't think that's in the standard library. For arrays, there's `.dup`: const int[] c = [1, 2, 3]; int[] m = c.dup;
Re: Function argument that is a pointer to memory which the function is not allowed to modify, as in C const
On Wednesday, March 14, 2018 22:23:47 Cecil Ward via Digitalmars-d-learn wrote: > say in C I have a function with a pointer argument > foo( const sometype_t * p ) > > I have asked about this D nightmare before. Using the same > pattern in D or the in argument qualifier as far as I can see the > value of the pointer is then itself effectively locked made > constant. Without dangerous and ugly casts you are stuck. > > q1. If you want a pointer to memory that is not to be modified > then you can't walk the pointer through that memory. So what are > my options? I need a pointer that I can increment. (I could avoid > the whole issue by using an index instead, but that seems to be > giving in to madness.) Once something is const, it can't be modified without violating the type system, so if you need to mutate something, it can't be const. However, with a pointer, you can have a mutable pointer to a const object (i.e. tail-const), e.g. const(sometype_t)* p; and in that case, the pointer can be mutated while still not being able to mutate what it points to. However, once the pointer itself is const, it can't be mutated, and you'd be forced to copy the pointer to get a tail-const pointer. > It seems to me that this is the worst thing I have seen about D. > Perhaps trying to make pointers unusable is a surreptious > strategt]y for encouraging designers to phase them out. Making > code unsafe just to get out of this nightmare (by casting or > giving up and dropping important const protection) is not the way. Code with pointers is @system where the compiler cannot guarantee that the operation is memory safe. Given the nature of pointers, that means that stuff like pointer arithmetic can't be treated as @safe. It works just fine, but it's then up to the programmer to verify the @safety of what's going on. D is only trying to discourage the use of pointers in the sense that any time that it's trying to proved memory safety, it tends to have to restrict code thoroughly enough that it can't do much with pointers. DIP 1000 will improve that, since it improves scope sufficiently that a lot more code using pointers will be able to be @safe, but fundamentally, pointers are sufficiently unrestricted that they quickly can't be proven to be memory safe. So, using them isn't forbidden, but their use does end up being restricted in any code that's trying to guarantee memory safety. However, there's no requirement that @safe be used, and you can use pointers pretty much as freely in D as you can in C/C++. As far as const goes, the way it works really has nothing to do with pointers one way or the other beyond the fact that it allows for tail-const so that pointers can be mutated while leaving the data const. const works the way that it does in D, because it has to in order to not violate immutable (since a pointer to const data could actually be pointing to immutable data), and because Walter believes that const is pointless if it doesn't provide strong compiler guarantees. So, unlike C++, D's const provides strong compiler guarantees, but it does make it restrictive enough that it's often unusable. The reasons behind it really have nothing to do with trying to discourage pointers though. > q2. If you want a pointer to modifiable memory but wish to ensure > that the value of that address stays fixed, stays where it's put, > then what on earth do you do. What are my options? > > Is there any way at all to campaign for a change to this > craziness? I doubt this is a democracy. It's also rather more > than a bit late. Early on in D2, const actually supported the notion of head-const, but it was deemed too complicated, and it really doesn't play well with immutable. As such, while you can use parens with const to have tail-const (thereby having a mutable pointer to const data), you can't have a const pointer to mutable data. Once a part of a type is const, everything inside it is const. However, you can wrap a pointer in a struct which allows you access to the data that the pointer points to without allowing access to the pointer itself, thereby effectively making the pointer read-only. It can't actually be const, and it's extra work to create such a wrapper struct, but it's quite possible if that's what you really want. > q3. The in keyword seems to be mixed up concerning the > distinction between modifiable arguments and modifiable memory. > Is there any way of making in usable for the purposes of > documenting the calling convention, showin which arguments are > inputs only, which are outputs and which are modified - > read-modified-returned? > > Apologies for my lack for my lack of familiarity with the > possible ways out of this. Originally in D2, in was a synonym for const scope (which, since scope has mostly been unimplemented effectively was the same as const). IIRC, it was an attempt to make porting D1 code to D2 easier, since D1 used in for something similar. Folks have often used in in D2 mainly because the
Re: What is the "right" way to create a generic type getter (and setter) ?
On 03/14/2018 11:13 PM, James Blachly wrote: Suppose I have a struct (which is really a memory map of a data file I am reading in) with too many data members to reasonably code getters/setters for by hand. I wish to either retrieve individual values or set individual values, which could be numeric, boolean, or string, from the command line, à la: $ prog -i inputfile.bin get field_name; (prints "300" or "false" or "Welcome to the jungle") $ prog -i inputfile.bin set some_field:9000 $ prog -i inputfile.bin set other_field:Whatever_String Each field itself is strongly typed, for what that's worth. So you've got a large struct like this (right?): struct S { int some_field; string other_field; /* ... more fields with arbitrary types ... */ } Approaches I have considered and implemented in part are: * templated getter (T get(T)(string field) {...}) but this approach requires knowledge of field types which I cannot reasonably expect to know at runtime(?) The return type needs to be known at compile time, but `field` is passed at run time. Can't work. * modification to the above whereby I could have an AA holding type information for each field, generated by static foreach {mixin ...}, although I cannot get this to work as my struct's static constructor complains (rightly) that it cannot work without knowing 'this' at compile time. Code: `mixin("field_types[\"" ~ prop ~ "\"] = typeid(this." ~ prop ~ ");");` Is there another __trait I am missing that will give me the type of the struct member without requiring an instance of the struct? You could use `typeid(typeof(this." ~ prop ~ "))`. But you can't use a run-time TypeInfo as a return type. So I don't think this gets you anywhere. I did manage to use metaprogramming inside my templated get function to handle numeric values, which was fascinating (although this is probably ugly code and it required a large enum array FIELDS): ``` GetterSwitch: switch (field) { static foreach(prop; FIELDS ) { mixin("case \"" ~ prop ~ "\": val = this." ~ prop ~ "; break GetterSwitch;"); } default: val = 0; assert(0); // This is to prevent subtle bugs, but I need a better error handler } ``` You can probably get around the (manually maintained?) `FIELDS` array with `.tupleof` or something similar: static foreach (i, f; S.tupleof) { case __traits(identifier, f): } Any pointers / design patterns on this particular type of problem class would be greatly appreciated. (Sidenote, I realize I could probably use the witchcraft library, but I am also using this as exercise to learn D beyond the basics). You simply cannot have a method that returns different types based on a run-time value. You could possibly return a std.variant.Variant. But if the goal is just to print the value to the screen, all you need is a string. So the signature would be `string get(string field)`. And for the implementation you could use `.tupleof` to iterate over all fields, and then return `f.to!string`. `set` can be done similarly. Take two `string`s: the field name, and the value. `static foreach` over all fields. On a match, convert the given value string to the type of the field that matched.
Function argument that is a pointer to memory which the function is not allowed to modify, as in C const
say in C I have a function with a pointer argument foo( const sometype_t * p ) I have asked about this D nightmare before. Using the same pattern in D or the in argument qualifier as far as I can see the value of the pointer is then itself effectively locked made constant. Without dangerous and ugly casts you are stuck. q1. If you want a pointer to memory that is not to be modified then you can't walk the pointer through that memory. So what are my options? I need a pointer that I can increment. (I could avoid the whole issue by using an index instead, but that seems to be giving in to madness.) It seems to me that this is the worst thing I have seen about D. Perhaps trying to make pointers unusable is a surreptious strategt]y for encouraging designers to phase them out. Making code unsafe just to get out of this nightmare (by casting or giving up and dropping important const protection) is not the way. q2. If you want a pointer to modifiable memory but wish to ensure that the value of that address stays fixed, stays where it's put, then what on earth do you do. What are my options? Is there any way at all to campaign for a change to this craziness? I doubt this is a democracy. It's also rather more than a bit late. q3. The in keyword seems to be mixed up concerning the distinction between modifiable arguments and modifiable memory. Is there any way of making in usable for the purposes of documenting the calling convention, showin which arguments are inputs only, which are outputs and which are modified - read-modified-returned? Apologies for my lack for my lack of familiarity with the possible ways out of this. q4. If my understanding is correct, it seems difficult to create a non const copy of (an address that is fixed) either; that is, making a modifiable copy of an address, one which can be incremented, moved upwards starting from a locked base address. It seems that declaring a pointer argument with const or even using the keyword in triggers this problem, the latter being particularly nightmarish because I would want in to mean that that argument (the address, which is what I am declaring) is merely an input-only parameter to the routine, or alternatively a locked /fixed address value which stay s put, and nothing. I'm interested in the cleanest safest techniques for digging myself out of this while always preserving const correctness, preventing possibility of writing to memory and preventing evil type changes where pointers end up pointing to some different kind of objects because if evil casting. I really don't want to use casts that have to much power, where they could allow overrides to any kind of bugs in or even create a new bug, including cases when things break because of duplication of types so later changes of types cause a bug because kludge contain duplicate type specifiers that do not get updated. There probably is a tool somewhere to safely create a modifiable object based on a const object but I'm not sure where to look. Any wise guidance appreciated mucky.
What is the "right" way to create a generic type getter (and setter) ?
For context, please keep in mind I am coming from a python background, but am very much enjoying strong typing, although it is taking some significant adjustment. Suppose I have a struct (which is really a memory map of a data file I am reading in) with too many data members to reasonably code getters/setters for by hand. I wish to either retrieve individual values or set individual values, which could be numeric, boolean, or string, from the command line, à la: $ prog -i inputfile.bin get field_name; (prints "300" or "false" or "Welcome to the jungle") $ prog -i inputfile.bin set some_field:9000 $ prog -i inputfile.bin set other_field:Whatever_String Each field itself is strongly typed, for what that's worth. Approaches I have considered and implemented in part are: * templated getter (T get(T)(string field) {...}) but this approach requires knowledge of field types which I cannot reasonably expect to know at runtime(?) * modification to the above whereby I could have an AA holding type information for each field, generated by static foreach {mixin ...}, although I cannot get this to work as my struct's static constructor complains (rightly) that it cannot work without knowing 'this' at compile time. Code: `mixin("field_types[\"" ~ prop ~ "\"] = typeid(this." ~ prop ~ ");");` Is there another __trait I am missing that will give me the type of the struct member without requiring an instance of the struct? I did manage to use metaprogramming inside my templated get function to handle numeric values, which was fascinating (although this is probably ugly code and it required a large enum array FIELDS): ``` GetterSwitch: switch (field) { static foreach(prop; FIELDS ) { mixin("case \"" ~ prop ~ "\": val = this." ~ prop ~ "; break GetterSwitch;"); } default: val = 0; assert(0); // This is to prevent subtle bugs, but I need a better error handler } ``` Any pointers / design patterns on this particular type of problem class would be greatly appreciated. (Sidenote, I realize I could probably use the witchcraft library, but I am also using this as exercise to learn D beyond the basics). Thanks in advance James
Re: Are there any working instructions about how to build and test dmd on Windows?
On Wednesday, 14 March 2018 at 00:43:52 UTC, Rubn wrote: Yah it's not fun. Some notes: You might need to set MSVC_CC environment variable cause it doesn't use the right format for VS path, depending on your version. https://github.com/dlang/dmd/blob/v2.079.0/src/vcbuild/msvc-dmc.d#L19 You could open a command prompt with the batch file running which will add variables used by the script. C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat You should be able to build it now with just: make -f win64.mak reldmd Thanks, but now I'm stuck on this: [...] vcbuild\msvc-dmc -cpp -o..\generated\windows\release\64\optabgen.exe dmd\backend\optabgen -DMARS -DDM_TARGET_CPU_X86=1 -Idmd\tk "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe" /nologo /Ivcbuild /Idmd\root /FIwarnings.h ^"/D_HAS_EXCEPTIONS=0^" ^"/Wv:18^" /TP /Fe..\generated\windows\release\64\optabgen.exe dmd\backend\optabgen.c -DMARS ^"-DDM_TARGET_CPU_X86=1^" /Idmd\tk optabgen.c optabgen.obj : error LNK2019: unresolved external symbol __report_rangecheckfailure referenced in function "void __cdecl dotytab(void)" (?dotytab@@YAXXZ) optabgen.obj : error LNK2019: unresolved external symbol __acrt_iob_func referenced in function printf optabgen.obj : error LNK2019: unresolved external symbol fclose referenced in function "void __cdecl dotab(void)" (?dotab@@YAXXZ) optabgen.obj : error LNK2019: unresolved external symbol fopen referenced in function "void __cdecl dotab(void)" (?dotab@@YAXXZ) optabgen.obj : error LNK2019: unresolved external symbol __stdio_common_vfprintf referenced in function _vfprintf_l optabgen.obj : error LNK2019: unresolved external symbol exit referenced in function "void __cdecl dotab(void)" (?dotab@@YAXXZ) optabgen.obj : error LNK2019: unresolved external symbol _wassert referenced in function "void __cdecl doreltables(struct _iobuf *)" (?doreltables@@YAXPEAU_iobuf@@@Z) optabgen.obj : error LNK2001: unresolved external symbol __GSHandlerCheck optabgen.obj : error LNK2019: unresolved external symbol __security_check_cookie referenced in function "void __cdecl doreltables(struct _iobuf *)" (?doreltables@@YAXPEAU_iobuf@@@Z) optabgen.obj : error LNK2019: unresolved external symbol __security_cookie referenced in function "void __cdecl doreltables(struct _iobuf *)" (?doreltables@@YAXPEAU_iobuf@@@Z) LINK : error LNK2001: unresolved external symbol mainCRTStartup C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\libcpmt.lib : warning LNK4272: library machine type 'X86' conflicts with target machine type 'x64' C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\LIBCMT.lib : warning LNK4272: library machine type 'X86' conflicts with target machine type 'x64' ..\generated\windows\release\64\optabgen.exe : fatal error LNK1120: 11 unresolved externals
Re: Why does struct initializer works for arrays but not for associative arrays?
On Wednesday, 14 March 2018 at 15:17:54 UTC, Jonathan M Davis wrote: On Wednesday, March 14, 2018 13:36:51 Andre Pany via Digitalmars-d-learn wrote: [...] Well, I think that you have two issues here: 1. Struct literals work in only a few, specific circumstances. Why, I don't know, but IIRC, someone was writing a DIP to fix that, and that may or may not fix this case. So, as I understand it, it's not all that hard to run into places where they don't work (I confess that I never use them, because I don't like them any more than I like the fact that struct constructors are implicitly declared if you don't declare them, which has caused me bugs when changing the members fo a struct; both are misfeatures IMHO, though obviously not everyone agrees on that point). 2. In general in D, the type of an expression is not inferred based on where it's used. There are a few exceptions where literals are involved, but in general, if you have something like A a = expression; expression has to evaluate correct on its own without taking A into account. The fact that something like Bar b = {s: "str"}; compiles is actually a bit of an oddity in D's semantics in that respect. So, the fact that it works at all is a bit of a special case, and clearly, they didn't get everything. My guess is that the problem is that the dynamic array literal needs a type, but the compiler is not set up to figure out what type that is based on the fact that it's being used in a struct literal. - Jonathan M Davis Thanks for the information. As it works fine for dynamic arrays and the coding in the compiler seems identical for arrays and associative arrays I really wonder why it not work. Although I really anticipate the DIP, this can be solved as bug fix. The chances to solve this a bug fix are much higher than getting the DIP implemented in near future (unfortunately). Kind regards André
Re: Why does struct initializer works for arrays but not for associative arrays?
On Wednesday, 14 March 2018 at 15:17:54 UTC, Jonathan M Davis wrote: On Wednesday, March 14, 2018 13:36:51 Andre Pany via Digitalmars-d-learn wrote: [...] Well, I think that you have two issues here: 1. Struct literals work in only a few, specific circumstances. Why, I don't know, but IIRC, someone was writing a DIP to fix that, and that may or may not fix this case. For reference, that's the DIP: https://github.com/dlang/DIPs/pull/71
Re: Why does file order matters when using -run option?
On Wednesday, 14 March 2018 at 14:44:24 UTC, Marc wrote: assume the files: app.d void main() { import myModule : foo; writeln(foo(...)); } myModule.d module myModule; int foo(int n) { } the following fail: dmd -run app.d mymodule.d give error like this: Error: module `myModule` is in file 'myModule.d' which cannot be read but this doesn't fail: dmd app.d mymodule.d && app Why does -run fail here? I thought it was a shorthand to this batch: dmd app.d mymodule.d app.exe del app.exe Not even that dmd mymodule.d -run app.d works and dmd -i -run app.d works too. However, at the moment -run needs to be the last parameter. That's a more or less arbitrary restriction. And no one has lifted it (yet). Though there's a bit of work on that front: https://github.com/dlang/dmd/pull/7927 The main problem is that the arguments after -run module are passed to the program and thus -run can be ambiguous.
Re: Why does struct initializer works for arrays but not for associative arrays?
On Wednesday, March 14, 2018 13:36:51 Andre Pany via Digitalmars-d-learn wrote: > Hi, > > I do not understand why struct initializer works for arrays but > not for > associative arrays: > > struct Bar > { > string s; > } > > struct Foo > { > Bar[string] asso; > Bar[] arr; > } > > void main() > { > Foo foo = { > arr: [{s: "123"}], > asso: ["0": {s: "123"}] // does not work > }; > } > > The coding for both types of arrays looks very similiar: > https://github.com/dlang/dmd/blob/9ed779a7d68d2ac489338cc4758c10d0cb169b39 > /src/dmd/initsem.d#L634 > > I cannot spot the difference. > > Kind regards > André Well, I think that you have two issues here: 1. Struct literals work in only a few, specific circumstances. Why, I don't know, but IIRC, someone was writing a DIP to fix that, and that may or may not fix this case. So, as I understand it, it's not all that hard to run into places where they don't work (I confess that I never use them, because I don't like them any more than I like the fact that struct constructors are implicitly declared if you don't declare them, which has caused me bugs when changing the members fo a struct; both are misfeatures IMHO, though obviously not everyone agrees on that point). 2. In general in D, the type of an expression is not inferred based on where it's used. There are a few exceptions where literals are involved, but in general, if you have something like A a = expression; expression has to evaluate correct on its own without taking A into account. The fact that something like Bar b = {s: "str"}; compiles is actually a bit of an oddity in D's semantics in that respect. So, the fact that it works at all is a bit of a special case, and clearly, they didn't get everything. My guess is that the problem is that the dynamic array literal needs a type, but the compiler is not set up to figure out what type that is based on the fact that it's being used in a struct literal. - Jonathan M Davis
Re: Why does struct initializer works for arrays but not for associative arrays?
On Wednesday, 14 March 2018 at 13:36:51 UTC, Andre Pany wrote: Hi, I do not understand why struct initializer works for arrays but not for associative arrays: struct Bar { string s; } struct Foo { Bar[string] asso; Bar[] arr; } void main() { Foo foo = { arr: [{s: "123"}], asso: ["0": {s: "123"}] // does not work }; } The coding for both types of arrays looks very similiar: https://github.com/dlang/dmd/blob/9ed779a7d68d2ac489338cc4758c10d0cb169b39/src/dmd/initsem.d#L634 I cannot spot the difference. Kind regards André This might just be a bug. Changing the initializer to an explicit call to Bar constructor compiles just fine https://run.dlang.io/is/nuuolx Even just doing Foo foo = { arr: [{s: "123"}], asso: ["0": {"123"}] // does not work };
Re: "Error: address of variable this assigned to this with longer lifetime"
On Wednesday, March 14, 2018 07:11:49 Nathan S. via Digitalmars-d-learn wrote: > On Tuesday, 13 March 2018 at 22:33:56 UTC, Jonathan M Davis wrote: > > And you can't get rid of it, because the object can still be > > moved, which would invalidate the pointer that you have > > referring to the static array. > > ... > > https://issues.dlang.org/show_bug.cgi?id=17448 > > Thanks for the info. Another way to tackle this problem is to not slice the static array but to keep track of either two indices or an index and the length explicitly and then use those with the static array. It's more annoying in some respects, but it solves the @safety problem. LOL. It was actually thanks to your post here that it clicked for me that I had this problem with some of my recent code. I was well aware of the problems with having pointers to structs on the stack, but it hadn't clicked that slicing a static array like that was the same thing until you posted about it. I had realized that having a dynamic array in the struct being a slice of a static array in the struct would cause problems when the struct was copied, and I'd dealt with that with a postblit constructor, but the issue with moving didn't click until I connected the dots between your post and that recent bugzilla issue. So, answering your question actually helped me catch a bug in my code. - Jonathan M Davis
Re: Why does file order matters when using -run option?
On Wednesday, 14 March 2018 at 14:44:24 UTC, Marc wrote: Why does -run fail here? I thought it was a shorthand to this batch: Check the help text: $ dmd -h dmd [...] -run [...] Argument to pass when running the resulting program Notice that there's only one file there. Everything after it is passed as args to the resulting program. So dmd -run cannot support multiple D files. Though, with the new `-i` option you might be able to get it to infer modules. dmd -i -run file_with_main.d args_to_main... and if it can locate the other modules automatically it should bring them in there.
Why does file order matters when using -run option?
assume the files: app.d void main() { import myModule : foo; writeln(foo(...)); } myModule.d module myModule; int foo(int n) { } the following fail: dmd -run app.d mymodule.d give error like this: Error: module `myModule` is in file 'myModule.d' which cannot be read but this doesn't fail: dmd app.d mymodule.d && app Why does -run fail here? I thought it was a shorthand to this batch: dmd app.d mymodule.d app.exe del app.exe
Why does struct initializer works for arrays but not for associative arrays?
Hi, I do not understand why struct initializer works for arrays but not for associative arrays: struct Bar { string s; } struct Foo { Bar[string] asso; Bar[] arr; } void main() { Foo foo = { arr: [{s: "123"}], asso: ["0": {s: "123"}] // does not work }; } The coding for both types of arrays looks very similiar: https://github.com/dlang/dmd/blob/9ed779a7d68d2ac489338cc4758c10d0cb169b39/src/dmd/initsem.d#L634 I cannot spot the difference. Kind regards André
Re: how to make private class member private
On Wednesday, 14 March 2018 at 04:30:17 UTC, Amorphorious wrote: On Wednesday, 14 March 2018 at 01:41:33 UTC, psychoticRabbit wrote: On Tuesday, 13 March 2018 at 21:38:59 UTC, Amorphorious wrote: You are a moron...etc..etc..etc..etc. See. This is what happens when you have access to a keyboard while high on ice. Yep. So maybe you should stop doing the ice?!?! Then maybe you could actually reply with an intelligent answer? How old are you, BTW? 15? You know that at that age ice is pretty bad for you. It will drop your IQ 20 points in a year, so since you obviously have an IQ of 60 then means you've been doing ice for about 1 year now... better stop while you have any brain cell's left. Please refrain from personal attacks! The forum should be a place people enjoy to be and can have professional discussion.
Re: RefRange behavior
On Wednesday, 14 March 2018 at 10:22:45 UTC, Alex wrote: Is there a simple workaround, maybe? ok, the workaround would be to enumerate the member and to use the former notation.
RefRange behavior
Hi all, given this: ´´´ import std.range; size_t[] arr; struct S { RefRange!(size_t[]) member; } void fun(ref size_t numByRef){} void main() { arr.length = 42; S s; s.member = refRange(&arr); static assert(__traits(compiles, fun(s.member[0]))); static assert(!__traits(compiles, fun(s.member.front))); //fun(s.member.front); /* source/app.d(19,5): Error: function `app.fun(ref ulong numByRef)` is not callable using argument types `(ulong)` source/app.d(19,5):cannot pass rvalue argument `s.member.front()` of type `ulong` to parameter `ref ulong numByRef` */ } ´´´ Why does the last static assert yields false? Is there a simple workaround, maybe?
Re: "Error: address of variable this assigned to this with longer lifetime"
On Tuesday, 13 March 2018 at 22:33:56 UTC, Jonathan M Davis wrote: And you can't get rid of it, because the object can still be moved, which would invalidate the pointer that you have referring to the static array. ... https://issues.dlang.org/show_bug.cgi?id=17448 Thanks for the info.