Re: Is it possible to call a delegate at compile time?
On Friday, 23 June 2017 at 04:58:07 UTC, ketmar wrote: Andrew Edwards wrote: so no, even if you'll remove `ref`, it will not work. sorry. Okay, got it. Much appreciated.
Re: Is it possible to call a delegate at compile time?
Andrew Edwards wrote: I desire to call foo() at compile... As implemented it does not happen, but it's not immediately clear what I am missing. Or is this simply not possible as yet? What is the proper way to redesign this template so that it will execute at compile time? there are two caveats. the first is `ref` in Args: that won't work for arguments in CTFE (it works for nested functions, though). and second, whith you can't fight right now: "Error: closures are not yet supported in CTFE". so no, even if you'll remove `ref`, it will not work. sorry.
Is it possible to call a delegate at compile time?
auto foo(Args...)(ref Args args) { with (Module!"std.conv") with (Module!"std.stdio") { return () => { string[] s; foreach (i, arg; args) { static if (is(Args[i] == string)) { s ~= arg; } else { s ~= to!string(arg); } } debug writeln(fmt()); return cast(immutable)s; }(); } } template Module(string name) { mixin("import Module = " ~ name ~ ";"); } void main() { static immutable i = 7; static immutable s = "teen"; static immutable res = foo(i, s)(); writeln(res); } I desire to call foo() at compile... As implemented it does not happen, but it's not immediately clear what I am missing. Or is this simply not possible as yet? What is the proper way to redesign this template so that it will execute at compile time? Thanks, Andrew
Re: BetterC and TypeInfo Question
On Friday, 23 June 2017 at 02:49:27 UTC, Mike wrote: I'm not sure what you have in mind, but TypeInfo in itself is not bad and has some very useful features even for resource constrained devices and other niche domains. Yeah, I agree with you. My approaches are right now for -betterC to be a filthy hack to get it working quick, and I still have a bunch of ways I want to improve the implementation and compiler interface in the main, non-hack-switch too. My wrist is sore today though so I gotta take a break... but I think you and I have the same goals in mind.
Re: BetterC and TypeInfo Question
On Friday, 23 June 2017 at 02:14:08 UTC, Adam D. Ruppe wrote: Yes, it is necessary, but how much? Can we do it with implicitly generated library code? I'm pretty sure the answer is "not much" and "yes", but I still need to ponder the details. I think the typeinfo for a class good enough for dynamic cast could be about half the size we have now. Though like I said, a lot of the stuff we have now is cool stuff, so I don't want to miss it entirely, it could be behind another pointer. I'm not sure what you have in mind, but TypeInfo in itself is not bad and has some very useful features even for resource constrained devices and other niche domains. The problem is that the current compiler-runtime requires it to exist just to get a build, even though it's not being used in the source code (implicitly or otherwise) and has no chance of ever being executed or referenced in the resulting binary. Also, TypeInfo has been overused in the compiler-runtime implementation. For example: http://forum.dlang.org/post/mrmv61$230i$1...@digitalmars.com The compiler should be able to generate the object code in a way that allows the linker to discard it, if it can't find anything that uses it. I think LTO has made such features even more intelligent. I'd like to see 3 improvements: 1. The compiler doesn't require TypeInfo to be implemented in the runtime if the user's code will never make use of it. 2. If TypeInfo is implemented in the runtime, the compiler generates the object code in a way that permits the linker to discard it if it can't find a link to it. 3. If only one item is needed out of TypeInfo, pass a reference to that instead of the entire TypeInfo object in the compiler-runtime implementation, so implementations can be made more granular. Or perhaps TypeInfo should be broken up into a few smaller types. Mike
Re: BetterC and TypeInfo Question
On Friday, 23 June 2017 at 00:41:11 UTC, sarn wrote: Does it matter? C++ programmers already accept that RTTI is needed for certain dynamic features. Yes, it is necessary, but how much? Can we do it with implicitly generated library code? I'm pretty sure the answer is "not much" and "yes", but I still need to ponder the details. I think the typeinfo for a class good enough for dynamic cast could be about half the size we have now. Though like I said, a lot of the stuff we have now is cool stuff, so I don't want to miss it entirely, it could be behind another pointer.
Re: struct template constructors
On Friday, 23 June 2017 at 00:54:36 UTC, Petar Kirov [ZombineDev] wrote: On Thursday, 22 June 2017 at 21:19:43 UTC, Boris-Barboris wrote: On Thursday, 22 June 2017 at 21:16:40 UTC, Ali Çehreli wrote: And yes, there should be one destructor, which may be a no-op if you grab its resource and set it to null. On all compilers... That's a relief, thank you for your help. On all compilers... ... modulo bugs. Closely Related: https://github.com/dlang/dmd/pull/6852 And also: https://github.com/dlang/dmd/pull/6847/files#diff-89369a835b853bb3725fd1d10d9c2d5d
Re: struct template constructors
On Thursday, 22 June 2017 at 21:19:43 UTC, Boris-Barboris wrote: On Thursday, 22 June 2017 at 21:16:40 UTC, Ali Çehreli wrote: And yes, there should be one destructor, which may be a no-op if you grab its resource and set it to null. On all compilers... That's a relief, thank you for your help. On all compilers... ... modulo bugs. Closely Related: https://github.com/dlang/dmd/pull/6852
Re: BetterC and TypeInfo Question
Currently a lot of language features generate dependencies on TypeInfo, arguably more than needed, but this is changing. Some examples are in this DConf 2017 talk: https://www.youtube.com/watch?v=endKC3fDxqs Also, the way the language is designed right now, all modules are responsible for containing TypeInfo instances for all their types, in case other modules *might* need them. So, if you define a plain old data struct, for example, you get TypeInfo and its runtime dependencies. This isn't a requirement, and Adam has just patched DMD to make -betterC leave out the TypeInfo. But, even in C++, RTTI is necessary for dynamic casting... so how is D going to address that? I think it is necessary, but can prolly be quite minimal. I will think about it more later. Does it matter? C++ programmers already accept that RTTI is needed for certain dynamic features.
Re: struct template constructors
On Thursday, 22 June 2017 at 21:16:40 UTC, Ali Çehreli wrote: And yes, there should be one destructor, which may be a no-op if you grab its resource and set it to null. On all compilers... That's a relief, thank you for your help.
Re: struct template constructors
On 06/22/2017 02:08 PM, Boris-Barboris wrote: On Thursday, 22 June 2017 at 20:05:46 UTC, Ali Çehreli wrote: To be complete, 'auto ref' passes lvalues by reference and rvalues by value, which you can detect with __traits(isRef): struct S{ } void foo()(auto ref S s) { static if (__traits(isRef, s)) { pragma(msg, "lvalue"); } else { pragma(msg, "rvalue"); } } void main() { auto s = S(); foo(s); foo(S()); } Ali Thank you very much! And the last question: Is it guaranteed an all compilers, that: 1). destructor for said rvalue is called only once. 2). function taking auto ref parameter gets that exact (memory-wise) rvalue, for example: struct S {} S produce() { return S(); } consume(produce()); void consume(auto ref S s) { // s passed by value, but is exactly that struct returned by produce, as if it // was RVO'd inside consume's stack frame. // and S destructor called only once on consume's scope escape? } I'm not sure whether it's RVO or moving in what condition, but yes, there will be no copy. You will get the bit representation of the constructed object. And yes, there should be one destructor, which may be a no-op if you grab its resource and set it to null. On all compilers... Ali
Re: struct template constructors
On Thursday, 22 June 2017 at 20:05:46 UTC, Ali Çehreli wrote: To be complete, 'auto ref' passes lvalues by reference and rvalues by value, which you can detect with __traits(isRef): struct S{ } void foo()(auto ref S s) { static if (__traits(isRef, s)) { pragma(msg, "lvalue"); } else { pragma(msg, "rvalue"); } } void main() { auto s = S(); foo(s); foo(S()); } Ali Thank you very much! And the last question: Is it guaranteed an all compilers, that: 1). destructor for said rvalue is called only once. 2). function taking auto ref parameter gets that exact (memory-wise) rvalue, for example: struct S {} S produce() { return S(); } consume(produce()); void consume(auto ref S s) { // s passed by value, but is exactly that struct returned by produce, as if it // was RVO'd inside consume's stack frame. // and S destructor called only once on consume's scope escape? }
Re: struct template constructors
On 06/22/2017 12:57 PM, Boris-Barboris wrote: > On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote: >> No time to think about the rest of the design but just to get the code >> compiled, replace 'ref' with 'auto ref' like so: > > Ok, looks like this indeed passes rhs by reference, thank you. To be complete, 'auto ref' passes lvalues by reference and rvalues by value, which you can detect with __traits(isRef): struct S{ } void foo()(auto ref S s) { static if (__traits(isRef, s)) { pragma(msg, "lvalue"); } else { pragma(msg, "rvalue"); } } void main() { auto s = S(); foo(s); foo(S()); } Ali
Re: struct template constructors
On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote: No time to think about the rest of the design but just to get the code compiled, replace 'ref' with 'auto ref' like so: Ok, looks like this indeed passes rhs by reference, thank you. destcalls - number of times UniquePtr destructor was called deallocs - number of times internal pointer was freed. unittest { deallocs = destcalls = 0; class A {} class B: A {} { UniquePtr!B b = UniquePtr!B.make(); assert(b.owner); { UniquePtr!A a = b; assert(!b.owner); assert(a.owner); assert(destcalls == 0); assert(deallocs == 0); } assert(destcalls == 1); assert(deallocs == 1); } assert(destcalls == 2); assert(deallocs == 1); }
Re: Dealing with the interior pointers bug
On 06/22/2017 08:38 PM, Boris-Barboris wrote: Casts are part of the type system. Yes, D type system allows invalid operations. It's not the compiler's fault, it's type system's fault. unittest { immutable int a = 4; int* b = cast(int*) *b = 5; assert(*() == 5); assert(a == 4); } This is just arguing semantics, of course, but I wouldn't say that the type system allows this specific invalid operation. Rather, with casting you can step out of the type system, and break its guarantees. Point is, you need a way to say that the operation is invalid. It's invalid because it breaks what `immutable` promises. `immutable` is part of the type, so I'd say the guarantee is part of the type system.
Re: struct template constructors
On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote: No time to think about the rest of the design but just to get the code compiled, replace 'ref' with 'auto ref' like so: this(DT)(scope auto ref UniquePtr!DT rhs) { // ... } Ali i added this static variable: static int destcalls = 0; changed constructor to: this(DT)(scope auto ref UniquePtr!DT rhs) { // here rhs releases pointer pragma(msg, typeof(rhs)); } wich prints "UniquePtr!(B)" on my machine, and destructor: ~this() { destcalls++; } Following code compiles and runs ok: class A {} class B: A {} UniquePtr!A a = UniquePtr!A.make(); assert(destcalls == 0); UniquePtr!A b = UniquePtr!B.make(); assert(destcalls == 1); Destructor is called for the result of "UniquePtr!B.make();", and if it actually was passed by value (wich is indicated by pragma's output), b's internal pointer would refer to freed heap block.
Re: Dealing with the interior pointers bug
On Thursday, 22 June 2017 at 19:11:19 UTC, Cym13 wrote: Here it's the programmer's fault really. You should never use casts in normal code, cast is the ultimate switch to say "Look, I know what I'm doing, so disable all safety, don't try to make sense of it, and let me do my thing. If I'm telling you it's a cat, then it is dammit.". You can't blame the type system not to do something coherent here, you explicitely went out of your way to lie to that very same type system in the most unsafe way possible. We're on the same page, I just think that ability to lie is part of the type system, that's all.
Re: struct template constructors
On 06/22/2017 12:06 PM, Boris-Barboris wrote: > Hi > > https://dpaste.dzfl.pl/0def4e286564 > > Is there a cleaner way to go than the one on the line 26? And why is the > constructor > > /d475/f781.d(37): f781.UniquePtr!(A).UniquePtr.__ctor(DT)(ref scope > UniquePtr!DT rhs) > > unfit for line 51? > Is it because the expression " = UniquePtr!B.make()" cannot be > interpreted as "scope ref"? It must release ownership of a pointer it > holds, and looks like it cannot do it in this form. (Going pedantic, you mean "struct constructor templates" or "templated struct constructors".) No time to think about the rest of the design but just to get the code compiled, replace 'ref' with 'auto ref' like so: this(DT)(scope auto ref UniquePtr!DT rhs) { // ... } Ali
Re: Dealing with the interior pointers bug
On Thursday, 22 June 2017 at 18:38:59 UTC, Boris-Barboris wrote: On Thursday, 22 June 2017 at 13:56:29 UTC, ag0aep6g wrote: For example, the type system guarantees that immutable data never changes. But the compiler allows you to cast from immutable to mutable and change the data. It's an invalid operation, but the compiler is not expected to catch that for you. Casts are part of the type system. Yes, D type system allows invalid operations. It's not the compiler's fault, it's type system's fault. unittest { immutable int a = 4; int* b = cast(int*) *b = 5; assert(*() == 5); assert(a == 4); } Here it's the programmer's fault really. You should never use casts in normal code, cast is the ultimate switch to say "Look, I know what I'm doing, so disable all safety, don't try to make sense of it, and let me do my thing. If I'm telling you it's a cat, then it is dammit.". You can't blame the type system not to do something coherent here, you explicitely went out of your way to lie to that very same type system in the most unsafe way possible.
struct template constructors
Hi https://dpaste.dzfl.pl/0def4e286564 Is there a cleaner way to go than the one on the line 26? And why is the constructor /d475/f781.d(37): f781.UniquePtr!(A).UniquePtr.__ctor(DT)(ref scope UniquePtr!DT rhs) unfit for line 51? Is it because the expression " = UniquePtr!B.make()" cannot be interpreted as "scope ref"? It must release ownership of a pointer it holds, and looks like it cannot do it in this form.
Re: Dealing with the interior pointers bug
On Thursday, 22 June 2017 at 13:56:29 UTC, ag0aep6g wrote: For example, the type system guarantees that immutable data never changes. But the compiler allows you to cast from immutable to mutable and change the data. It's an invalid operation, but the compiler is not expected to catch that for you. Casts are part of the type system. Yes, D type system allows invalid operations. It's not the compiler's fault, it's type system's fault. unittest { immutable int a = 4; int* b = cast(int*) *b = 5; assert(*() == 5); assert(a == 4); }
Re: Is there s.th. like enforceSuffix for arrays (string)?
On Thu, Jun 22, 2017 at 06:18:22PM +, Andre Pany via Digitalmars-d-learn wrote: > Hi, > > i often need to check whether an array(string) ends with a specific > text and if not I need to add this text. > > For example I have a variable url and / has to be added to the end in > case it is missing. > > I want to write: > ...new RegistryPackageSupplier(URL(url.enforceSuffix("/"))... > > Of course the logic is rather simple to implement on my side but I > often has this requirement and I cannot believe this functionality is > missing in Phobos. [...] What about: import std.string : chomp; url.chomp('/') ~ '/' The .chomp removes the "/" if there's one, then the ~ adds it back in either way, so the result always ends with "/". Phobos provides the primitives to build what you need, but it's a little unreasonable to expect that it should provide names for every possible combination of existing functions -- we'd run out of names because of combinatorial explosion. T -- Life is too short to run proprietary software. -- Bdale Garbee
Is there s.th. like enforceSuffix for arrays (string)?
Hi, i often need to check whether an array(string) ends with a specific text and if not I need to add this text. For example I have a variable url and / has to be added to the end in case it is missing. I want to write: ...new RegistryPackageSupplier(URL(url.enforceSuffix("/"))... Of course the logic is rather simple to implement on my side but I often has this requirement and I cannot believe this functionality is missing in Phobos. Have I missed it in the documentation? Kind regards André
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 run on Windows, and produce binaries that run on GNU/Linux.
Re: Dealing with the interior pointers bug
On 6/21/17 1:23 PM, H. S. Teoh via Digitalmars-d-learn wrote: 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. There are actually two categories of reasons: Design and Implementation. In the Design category, D can never have a truly precise scanning capability because of void * and unions. These two features would be impossible to determine what the actual layout of pointers for a given block actually is. In the Implementation category, precise scanning (to a certain degree) is achievable. But the current GC treats all blocks as "every size_t.sizeof bytes are a pointer" or "there are no pointers". With a better understanding of the layout of memory, the GC could be smarter about scanning. However, there are costs to the complexity. In addition, the GC does not know the stack layout of memory. So the stack can always create false pointers as it must be scanned conservatively. We could potentially create a precise map of the stack, but that involves either restricting the compiler from reassigning stack data to mean something else, or keeping a running map of what stack data is actually used. Both don't seem appealing to a performance-oriented language (system) language. Add alloca to the design category of memory that can't be precisely scanned as well. So we could do better in this front, but I don't know that it will happen because of the performance concerns. Rainer Schuetze implemented a precise scanner a while back, and did a dconf talk on it. So it is definitely possible (to a certain degree). -Steve
Re: BetterC and TypeInfo Question
On Thursday, 22 June 2017 at 14:50:45 UTC, Adam D. Ruppe wrote: [snip] I appreciate the reply.
Re: BetterC and TypeInfo Question
On Thursday, 22 June 2017 at 14:30:31 UTC, jmh530 wrote: I was looking through the C++ standard library headers and noticed that has a typeid also. One difference with D is that it is opt-in as there is some cost using it. C++ also leaves most the properties for typeinfo to be implementation defined, meaning things like .name can just return an empty string. I believe the only thing the standard requires is consistent opEquals. Additionally, C++ will only generate it for classes with at least one virtual member (the main use of it is dynamic casts, or substitutes thereof, and using those is often bad object oriented design anyway!) I suppose I'm wondering what other differences there are. Could TypeInfo be made optional in D, like it is in C++? Much of it can, yes, and it can also be defined to offer less (or more! I'm actually a fan of runtime reflection) than it does now. There's an effort to convert typeinfo to be library templates instead of a compiler-provided blob like it is now. But, even in C++, RTTI is necessary for dynamic casting... so how is D going to address that? I think it is necessary, but can prolly be quite minimal. I will think about it more later.
BetterC and TypeInfo Question
I should preface this by saying I don't really have a good sense of how either BetterC or the D runtime work. The recent BetterC thread made me wonder about TypeInfo in the D runtime. My (surface level) understanding is that this is what makes typeid work at run time. I was looking through the C++ standard library headers and noticed that has a typeid also. One difference with D is that it is opt-in as there is some cost using it. I suppose I'm wondering what other differences there are. Could TypeInfo be made optional in D, like it is in C++?
Re: Dealing with the interior pointers bug
On 06/22/2017 12:34 PM, Boris-Barboris wrote: Everything the language allows to compile is allowed by it's type system, or is a bug in the compiler. No. D is not supposed to be completely verifiable by the compiler. For example, the type system guarantees that immutable data never changes. But the compiler allows you to cast from immutable to mutable and change the data. It's an invalid operation, but the compiler is not expected to catch that for you.
Re: Dealing with the interior pointers bug
On Thursday, 22 June 2017 at 09:45:09 UTC, Russel Winder wrote: I think the term "systems programming language" contains no actual data, so needs to be retired. In this situation it provides no reason for conservative garbage collection. It means the intent of language designer to let you write operating system with his language, wich implies certain building blocks available to you. Whether it actually allows it or not is another question. Why should any language allow anything outside the type system. Everything the language allows to compile is allowed by it's type system, or is a bug in the compiler. Strong typing means strong typing Define strong typing then. Pointer is part of the type system, all casts and operations on it are too. If you pass wrongly-typed pointer, it won't compile. Maybe then the fault is having a weak type system, as any language is that allows ints to be pointers and vice versa. What's wrong with pointers in a language? You're not forced to use them, you know? But some tasks force you. If you seek compile-time verifyability, use different coding patterns \ languages, designed around this intent. Maybe type systems should be strong and all FFI be by value with no references to memory allowed? No, they definetly should not. Why can't GC use staticaly available type info (all pointer\reference variables and fields are visible in program text, why not just scan only them)? I don't know, probably it's harder, since it requires more cooperation between compiler and runtime, and increases GC signature (you have to store a huge list of pointers to all pointers on all stacks (and probably heap too), and compiler should generate code to populate this list on every function call). At this point you would be better off with RAII, wich will be more efficient and explicit and do exactly what you tell it to do.
Cannot implicitly convert expression (struct this)
Hi, I created a custom type which enables me to have enums which have in their initial state, the init value of their base type. Something similiar to Nullable... enum Reason : string {CO = "Co", FU = "Fu", CA = "Ca"} struct TestStruct {InitialEnum!Reason reason;} This line raises the error: TestStruct s2 = TestStruct(Reason.FU); Error: cannot implicitly convert expression ("Fu") of type Reason to InitialEnum!(Reason) While this line is working fine: TestStruct s1 = {reason: Reason.FU}; What do I miss? Kind regards André struct InitialEnum(T) { import std.traits: OriginalType, EnumMembers; import std.conv: to; private T _value; private bool _isEmpty = true; alias EnumBaseType = OriginalType!T; @property EnumBaseType baseTypeValue() { return (_isEmpty) ? EnumBaseType.init : _value; } @property T value() { return _value; } @property bool isEmpty() { return _isEmpty; } alias baseTypeValue this; void opAssign(EnumBaseType value) { if (value == EnumBaseType.init) { _isEmpty = true; return; } foreach (member; EnumMembers!T) { if (value == member) { _value = member; _isEmpty = false; return; } } throw new Exception("Value "~value.to!string~" is not a valid enum value"); } this(T t) { _isEmpty = false; _value = t; } this(EnumBaseType value) { opAssign(value); } }
Re: Dealing with the interior pointers bug
On Wed, 2017-06-21 at 10:23 -0700, H. S. Teoh via Digitalmars-d-learn wrote: > […] > > 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. I think the term "systems programming language" contains no actual data, so needs to be retired. In this situation it provides no reason for conservative garbage collection. Interfacing with a foreign language, not just C, does bring problems, but only if there is a shared address space, or the type system is weak or allows unions including pointers. > 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. Why should any language allow anything outside the type system. Strong typing means strong typing (*). > 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. Maybe then the fault is having a weak type system, as any language is that allows ints to be pointers and vice versa. Maybe type systems should be strong and all FFI be by value with no references to memory allowed? > 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. If there is a problem for 32-bit there is a problem for 64-bit. If it is possible it will happen. (*) OK, this joke probably only works in the UK. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Manually calling postblots recursively
On Sunday, 18 June 2017 at 14:16:03 UTC, Basile B. wrote: On Sunday, 18 June 2017 at 09:41:01 UTC, Johannes Loher wrote: Hey, I'm trying to work on https://issues.dlang.org/show_bug.cgi?id=15708 so I decided it might be interesting to find a way to (recursively) call all postblits that belong to certain struct or static array. This is what I came up with so far: [...] "@disable" postblits are detected as valid postblits. I think that you have to AndAnd the detection with std.traits.isCopyable Here is my new version. Additionally to taking care of @disable this(this); I added compile time checks if the underlying fields have an "elaborate copy constructor" so that I only call callPostblits on them if needed. Is this reasonable? It increases compiletime, but could possibly decrease runtime a little. On the other hand, the empty function calls should probably just get optimized away...? While doing all that I realized that hasElaborateCopyConstructor is true for structs with @disable this(this). Is that intended? It looks a bit weird to me... import std.traits; void callPostblits(S)(ref S s) { static if (isStaticArray!S && S.length && hasElaborateCopyConstructor!(ElementType!S)) { foreach (ref elem; s) callPostblits(elem); } else static if (is(S == struct)) { foreach (field; FieldNameTuple!S) { static if (hasElaborateCopyConstructor!(typeof(__traits(getMember, s, field { callPostblits(__traits(getMember, s, field)); } } static if (hasMember!(S, "__postblit") && isCopyable!S) { s.__postblit(); } } } unittest { struct AnotherTestStruct { int b = 0; this(this) { b = 1; } } struct TestStruct { int a = 0; this(this) { a = 1; } AnotherTestStruct anotherTestStruct; } TestStruct[2] testStructs; assert(testStructs[0].a == 0 && testStructs[0].anotherTestStruct.b == 0); assert(testStructs[1].a == 0 && testStructs[1].anotherTestStruct.b == 0); callPostblits(testStructs); assert(testStructs[0].a == 1 && testStructs[0].anotherTestStruct.b == 1); assert(testStructs[1].a == 1 && testStructs[1].anotherTestStruct.b == 1); struct YetAnotherTestStruct { @disable this(this); } YetAnotherTestStruct yetAnotherTestStruct; callPostblits(yetAnotherTestStruct); // This will also compile }
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.