Re: odd use of preprocessor
On 2011-11-06 19:43:15 +, Ellery Newcomer said: /* Error values. */ enum { DW_TAG_invalid = 0 #define DW_TAG_invalid DW_TAG_invalid }; It's strange all right. The only reason I can come with is that they want to prevent someone else from defining DW_TAG_invalid as a preprocessor value that would shadow the enum value. Just ignore it, D has no preprocessor. :-) -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Segmentation fault on closing file in destructor
On 2010-09-26 10:06:33 -0400, "Simen kjaeraas" said: Tom Kazimiers <2voo...@gmx.de> wrote: Hi, a file reading class of mine can be constructed with a filename as parameter. It instantiates a new std.stream.File (without the passed file name and closes it when opened within the destructor. The last part is where things are getting unclear for me. On the "file.isOpen()" call in the destructor a segmentation fault occurs. What is the problem with that? Likely, it is this[1]: "[T]he order in which the garbage collector calls destructors for unreference objects is not specified. This means that when the garbage collector calls a destructor for an object of a class that has members that are references to garbage collected objects, those references may no longer be valid. This means that destructors cannot reference sub objects." [1]: http://digitalmars.com/d/2.0/class.html#destructors That's it indeed, but I'll add that it's the File struct that is at fault. See this bug: <http://d.puremagic.com/issues/show_bug.cgi?id=4624> To make it short: when the File struct is located somewhere in the GC heap (like inside a class), File's destructor is buggy when a file is open. The only workaround I can think of is to call close() or detach() on the file struct before the garbage collectors kicks in (doing it in the destructor of your class is already too late, it must be done before the destructor gets called). In fact, it's generally a good idea to not wait for the GC to collect your objects before closing files, because waiting for the GC could take an indeterminate amount of time and leave files open for a long time (the GC only runs when needed). -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Linking D and Obj-C code into a Cocoa app proper? (Mac)
On 2010-10-05 10:02:45 -0400, Heywood Floyd said: But, sometimes I get reeeaally weird bugs. I had one bug where if I added an empty function to a class in D I got EXC_BAD_ACCES (segfault). An empty function! Ie "void f(){}". Remove the function--it works. In the debugger, I got the impression maybe the stack has got messed up, but I don't know, the debugger just shows assembler code, and I don't have the proper skills. It's hard to say without further details, but it could be that you're not recompiling everything that uses the class where you add a function. Unlike in Objective-C, adding a function to a D class breaks most compiled code that uses that class (because you're adding an offset to the virtual function table), so you need to recompile every D module that uses that class (or a derived class). Note that this is totally unrelated to having Objective-C code in the same program. This got really frustrating, needless to say, so I started playing around with the build settings. I switched from using LLVM 1.5 (for the obj-c code) to gcc 4.2. And now it magically seems to work! Are you using D for Xcode? By doing that you basically force everything to be recompiled, which solves problem described above. [...] == Question == How do you make D code and Obj-C code coexist? That is, I want to write a Cocoa-app that is mostly written in D, and with a little "glue"-code in Objective-C. How do you set that up? Is it even supposed to be possible? It is totally possible, and not that hard. Communicating via `extern (C)` functions should work well. (And what could the bug above be? I know LLVM does link-time optimizations, and even run-time optimizations. Could it be that it messes things up?) I doubt LLVM optimizations have anything to do with your problem. Things to keep in mind when mixing Objective-C: 1. Apple's Objective-C GC isn't supported by D, so you it's probably safer to use manual memory management (retain/release) on the Objective-C site. 2. Exceptions are not compatible between the two runtimes. Throwing can cause unexpected results when it unwinds stack frames in the other language. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Operator precedence of "new"
On 2010-10-15 08:12:24 -0400, bearophile said: Currently to call a method to a newly build object/struct you need: (new Foo).bar(); But isn't it better to change the D operator precedence rules a bit and allow new to bind more closely than the method call, to allow a syntax like: new Foo.bar(); Do you see bad side effects in this D2 change? But then, how does that work? new Foo.SubType.bar(); Could work like this: new (Foo.Subtype).bar(); which doesn't look too bad as long as .bar() is at the end. Remove it and you'll get this: new (Foo.Subtype); Hardly interesting, and somewhat counter-intuitive. That's especially bad considering that all types are in reality enclosed module name which can be made explicit: new (std.stdio.File); I much prefer that this works: new std.stdio.File; new Foo.Subtype; Even if it means I have to do: (new Foo).bar(); -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: common types + type modifiers
On 2011-01-29 20:09:11 -0500, Ellery Newcomer said: trying to wrap my head around shared,const,immutable (not inout yet, though someday I'll need to figure out what it's supposed to do) Currently, dmd doesn't exhibit a lot of consistency wrt the above, so bear with me as I question every ing thing it does. my [erroneous?] understanding of the modifiers: shared - many threads can see lack of shared - one thread can see plus some difference or other in physical layout (of which I am mostly ignorant) immutable - nobody can mutate lack of immutable - anybody can mutate const - either immutable or mutable - you can't mutate because you don't know which, but you also can't rely on it not mutating shared(immutable(T)) == immutable(T) because who care who can see it if nobody can mutate it otherwise, shared(T) != T where T is not shared or immutable because T might be mutable and then it matters who can see it and when What is the common type of two types with the same base T but different modifiers? My [erroneous?] [generic] reasoning: (notation - i under T1 means T1 == immutable(T), etc) T1 :T2 -> ResultT i c cfollows from my defs above i m cditto c m cditto I think this is what dmd does. seems obvious. Everything is correct up to here. what about shared? shared(U) : U -> ?? where U is not shared or immutable the result is some sort of a 'maybe shared' - it definitely can't be U. Can it be shared(U) ? I'm not sure about the semantics of tls, but it seems like that would violate U's contract that only one thread can see [and mutate] it. So it seems to me that there is no common type of shared(U) and U. Indeed, U and shared(U) have no common type. unless it's acceptable to just make the mutability const. which would give: csm cs csc cs msm cs msc cs No, that doesn't work. There is no common type between shared and non-shared. otherwise, its a shared/shared or immutable/shared pair, so the result type is shared, and the mutability is the same as for unshared/unshared. which, come to think of it, will always be const. So the result type will be const shared(T) So that's my generic reasoning, which doesn't take the semantics of subtypes, ease of use, etc, into account. here are some cases which I suspect are wrong: const(int) : int -> int const(int) : shared(int) -> int and shared(const(int*)) : const(int*) -> const(int)* 1) why can we do away with the constness of the pointer? 2) I think we should not do away with the sharedness of the pointer, let alone of the element (shared is transitive too, isn't it? it has to be..) About the constness of the pointer, you should only be able to do this when you make a copy of the pointer, as in: const(int*) a; const(int)* b = a; There is no const violation here because pointer 'b' is a new variable, distinct of 'a'. The data it points to however is the same, so the 'int' must stay const. That said, shared(const(int*)) and const(int*) do not have a common type since one is shared and the other is not. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: common types + type modifiers
On 2011-01-30 13:23:16 -0500, Ellery Newcomer said: Ah, thank you. That clears things up a bit. how do you safely convert from a shared type to a non shared type or vice versa? a deep copy inside a critical section? A copy? Yes. A critical section? Not really. Shared is about atomic operations, things that the processor can do atomically without locking. They're used mostly to provide sequential consistency in our multi-core world where multiple cores can see a different value for the same memory address at one given time due to out-of-sync caches. Atomic ops forces the caches to synchronize but are slower. You can't mix atomic operations with OS-level locking because they don't respect each other (a lock won't prevent an atomic read from occurring). Also, atomic ops are generally limited to word-sized data structures, sometime double-word. So on a 32-bit processor that's a 32-bit or 64-bit value (assuming the value is properly aligned). If you want to use locking (a critical section in Windows parlance), you should put your data in a synchronized class, then share that class with other threads. If you don't use locking, you have at best double-word granularity. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: std.concurrency & immutable classes...
On 2011-02-06 16:55:36 -0500, Tomek Sowiński said: ... doesn't work. class C {} thisTid.send(new immutable(C)()); receive((immutable C) { writeln("got it!"); }); This throws: core.exception.AssertError@/usr/include/d/dmd/phobos/std/variant.d(285): immutable(C) And when I go for Rebindable, I get "Aliases to mutable thread-local data not allowed.". Is there anything I can do? Overall, I think that's another reason D needs native tail const badly. Polymorphic classes are close to being second class citizens just as soon const enters. :( I just made this pull request today: <https://github.com/D-Programming-Language/dmd/pull/> If you want to test it, you're very welcome. Here is my development branch for this feature: <https://github.com/michelf/dmd/tree/const-object-ref> -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: std.concurrency & immutable classes...
On 2011-02-06 20:09:56 -0500, Michel Fortin said: I just made this pull request today: <https://github.com/D-Programming-Language/dmd/pull/> That should have been: <https://github.com/D-Programming-Language/dmd/pull/3> -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: std.concurrency & immutable classes...
On 2011-02-07 17:11:08 -0500, Tomek Sowiński said: Michel Fortin napisał: I just made this pull request today: <https://github.com/D-Programming-Language/dmd/pull/> If you want to test it, you're very welcome. Here is my development branch for this feature: <https://github.com/michelf/dmd/tree/const-object-ref> Thanks for doing this. Is it approved by Walter? Depends on what you mean by "approved". He commented once on the newsgroup after I posted an earlier version of the patch, saying I should add tests for type deduction and some other stuff. This change his something he attempted to do in the past and failed, I expect him to be skeptical. I guess he'll review it when he has the time and I hope he'll merge these changes in the mainline. He'll probably want to take his time however, since it can break existing code in some cases; it's basically a change to the language. If you want to show your support, I guess you can vote up the enhancement request in the bugzilla. <http://d.puremagic.com/issues/show_bug.cgi?id=5325> Also feel free to compile it, test it, and share your experience. The more tested it is, the more used and appreciated it is, the more exposure it gets, the sooner it gets approved, or so I guess. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: std.concurrency & immutable classes...
On 2011-02-10 14:45:14 -0500, Tomek Sowiński said: Michel Fortin napisał: Thanks for doing this. Is it approved by Walter? Depends on what you mean by "approved". He commented once on the newsgroup after I posted an earlier version of the patch, saying I should add tests for type deduction and some other stuff. This change his something he attempted to do in the past and failed, I expect him to be skeptical. It would be much easier if he provided the specific case(s) which broke his teeth. Then we'll all know where's the problem. I don't think he had much time to look at the patch. His last remark were more of like "I'm skeptical it can work, please make sure you have tests to cover those specific cases..." followed with a list of things to test. I'll surely get some feedback on my patch someday, hopefully right after the next release (which should be imminent now). The architecture of the DMD front end makes it very difficult to approach the tail-const problem for classes the same way it works for pointers. If this is what Walter tried, I have no difficulty understanding why it didn't go very far. My approach was to make the optional 'ref' a modifier that changes the attributes of a new head type attached to classes. This may look a little of a hack, but it works. If it's soluble, it'll ope n the door to tail type modifiers in general, not just in classes. It's a b urning issue e.g. with ranges (mostly struct). http://d.puremagic.com/issues/show_bug.cgi?id=5377 Look at the attachment to get a feel of what hoops we'll have to jump throu gh to side-step lack of tail X. Passing 'this' by reference in struct member functions makes it pretty much impossible to support tail const. The reason it works for classes is that class member functions receive a *copy* of the 'this' object reference, in other words the constness of the original reference does not matter. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: assert(expression, error)
On 2011-02-12 10:05:34 -0500, Andrej Mitrovic said: Btw, is the inline problem just a DMD implementation problem, or does enforce have to be fixed for that? DMD implementation problem. The inliner doesn't support ref, out, lazy, and delegate arguments at this time. Enforce uses a lazy second argument so it doesn't get inlined. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Struct reference returning function and const members
On 2011-03-03 01:42:18 -0500, Tom said: I have... int main(string[] args) { auto s1 = f(); // MH MH auto s2 = g(); // OK s2.c = null; // OK return 0; } I think the compiler complains because the s1.c member is not assignable (since it is const), so you can't assign to s1 as a whole. That said, it should probably be allowed for an initialization assignment like this one. I suggest you add it to the bug tracker. <http://d.puremagic.com/issues/> -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Deducing types for function templates
On 2011-03-15 10:42:46 -0400, Magnus Lie Hetland said: I've got a function template along these lines: Foo!T foo(T)(T[] bar, real function(T,T) baz) { ... } The main reason I'm using this is that it seems necessary to use a function, rather than a type (such as Foo), if you want the compiler to deduce the compile-time parameters. (Right?) Now ... this works just fine. However, if I try to add "const" before "T[]", DMD no longer groks it. Is that how it shold be? Seems awkward to me... (Or maybe I'm just doing it wrong?) I'd say add it to bugzilla. It's probably related to this bug: <http://d.puremagic.com/issues/show_bug.cgi?id=5531> And a followup question: Writing out the type of baz like this (in several places) is also a bit awkward. I'd like to have a template so I could just do Foo!T foo(T)(T[] bar, baz_t!T baz) { ... } However, I haven't been able to define such a template without running into the same problem (i.e., that DMD no longer can deduce what T should be from my arguments). My feeling is that it should work. Feel free to file a bug or enhancement request in the bug tracker. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Deducing types for function templates
On 2011-03-15 13:20:30 -0400, "Simen kjaeraas" said: On Tue, 15 Mar 2011 17:36:04 +0100, Michel Fortin wrote: On 2011-03-15 10:42:46 -0400, Magnus Lie Hetland said: I've got a function template along these lines: Foo!T foo(T)(T[] bar, real function(T,T) baz) { ... } The main reason I'm using this is that it seems necessary to use a function, rather than a type (such as Foo), if you want the compiler to deduce the compile-time parameters. (Right?) Now ... this works just fine. However, if I try to add "const" before "T[]", DMD no longer groks it. Is that how it shold be? Seems awkward to me... (Or maybe I'm just doing it wrong?) I'd say add it to bugzilla. It's probably related to this bug: <http://d.puremagic.com/issues/show_bug.cgi?id=5531> Oh, it's much older than that: http://d.puremagic.com/issues/show_bug.cgi?id=2128 I'm not sure it's the same thing, but I realize it's hard to say given Magnus in his original post didn't mention how he attempts to instantiate the template. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Want to help DMD bugfixing? Write a simple utility.
On 2011-03-19 20:41:09 -0400, Jonathan M Davis said: On Saturday 19 March 2011 17:11:56 Don wrote: Here's the task: Given a .d source file, strip out all of the unittest {} blocks, including everything inside them. Strip out all comments as well. Print out the resulting file. Motivation: Bug reports frequently come with very large test cases. Even ones which look small often import from Phobos. Reducing the test case is the first step in fixing the bug, and it's frequently ~30% of the total time required. Stripping out the unit tests is the most time-consuming and error-prone part of reducing the test case. This should be a good task if you're relatively new to D but would like to do something really useful. Unfortunately, to do that 100% correctly, you need to actually have a working D lexer (and possibly parser). You might be able to get something close enough to work in most cases, but it doesn't take all that much to throw off a basic implementation of this sort of thing if you don't lex/parse it with something which properly understands D. Well, I made simple lexer for D strings, comments, identifiers and a few other tokens which should be up to that task. It's what I use to parse files and detect dependencies in D for Xcode. Unfortunately, it's written in Objective-C++ (but half of it is plain C)... <https://github.com/michelf/d-for-xcode/blob/master/Sources/DXBaseLexer.h> <https://github.com/michelf/d-for-xcode/blob/master/Sources/DXBaseLexer.mm> <https://github.com/michelf/d-for-xcode/blob/master/Sources/DXScannerTools.h> <https://github.com/michelf/d-for-xcode/blob/master/Sources/DXScannerTools.m> Very short unit test: <https://github.com/michelf/d-for-xcode/blob/master/Unit%20Tests/DXBaseLexerTest.mm> -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: File, line and message for assert(0)?
On 2011-05-28 12:32:59 -0400, simendsjo said: I don't think I understand the use case for assert(0) then.. I thought it was just a way getting assert in release mode. The use case for assert(0) is the same as any assert(whatever): checking for things that shouldn't happen. Normally compiling in release mode would strip all the asserts to make things slimmer and faster. But given there is no cost in checking for assert(0), those are not stripped, they are just replaced with a halt instruction. So the assert's still there, but you don't have a message for it nor the line number. If you want to see where the assertion happens, you can either compile in non-release mode or you can hook a debugger to your release executable and wait for the assert to happen. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Pure not acting pure.
On 2011-06-15 23:29:46 -0400, Charles McAnany said: Ah, so does the compiler figure out which ones are strongly and weakly pure and then optimize as appropriate? Is there a way to indicate that a function is strongly pure? Because it would seem odd to call a function you thought was pure and wind up with a mutated argument. Just make sure all the parameters are either const or immutable or passed by copy and do not contain any pointer or reference. That'll make the function strongly pure, and the compiler will be able optimize. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: is this a poly Polymorphism?
On 2011-08-29 01:58:30 +, Jonathan M Davis said: On Monday, August 29, 2011 04:50:09 hhaammaadd wrote: import std.stdio; class employee { void work() { writeln("I am employee"); } } class manager: employee { void work() { writeln("I am manager"); } } void main() { employee e1 = new manager;//here e1.work(); manager m3 = new manager;//--|here employee *e2 = &m3;//| e2.work(); } Pointers are not polymorphic in D. Class references are, but if you have a pointer to a class, it assumes that the type is exactly that type and determines its function calls at compile time rather than at runtime. Actually, a pointer to a class is really a pointer to a reference to an object, since the reference is always with a class type. So "employee *" is in reality a pointer to a reference to an employee object. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: integer cast in object_.d
On 2011-09-05 02:57:33 +, Andrej Mitrovic said: I'm looking at compare() in class TypeInfo_Array and it's defined as: override int compare(in void* p1, in void* p2) { void[] a1 = *cast(void[]*)p1; void[] a2 = *cast(void[]*)p2; size_t sz = value.tsize(); size_t len = a1.length; if (a2.length < len) len = a2.length; for (size_t u = 0; u < len; u++) { int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz); if (result) return result; } return cast(int)a1.length - cast(int)a2.length; } Shouldn't that return line be: return cast(int)(a1.length - a2.length); To make it 64-bit safe? Per the rules of modular arithmetic substraction, both will give you the same result actually. And no it isn't 64-bit safe. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: WinRT
On 2011-09-29 21:23:48 +, RenatoL said: Hi all. What do you about WinRT? I think this new APIs could be a very interesting point for D... they are open to any language and i think that D is perfect to work with them. What's your opinion? Best regards From what I understand, WinRT is based on COM. D already supports COM, so it might already be doable by declaring the right interfaces as derivatives of IUnknown. I suggest you give it a try. That said, the automatic reference counting they added to WinRT types in Visual C++ won't be available without compiler support (but you can do it manually), and neither will the compiler-generated reflection data (you'll have to generate it yourself). -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: WinRT
On 2011-09-30 14:05:28 +, Jacob Carlborg said: On 2011-09-30 12:58, Michel Fortin wrote: On 2011-09-29 21:23:48 +, RenatoL said: Hi all. What do you about WinRT? I think this new APIs could be a very interesting point for D... they are open to any language and i think that D is perfect to work with them. What's your opinion? Best regards From what I understand, WinRT is based on COM. D already supports COM, so it might already be doable by declaring the right interfaces as derivatives of IUnknown. I suggest you give it a try. That said, the automatic reference counting they added to WinRT types in Visual C++ won't be available without compiler support (but you can do it manually), and neither will the compiler-generated reflection data (you'll have to generate it yourself). Doesn't the garbage collector implement reference counting or similar when implementing from IUnknown? Would be great, but it's not mentioned in the language spec so I somewhat doubt it. <http://www.d-programming-language.org/interface.html#COM-Interfaces> -- Michel Fortin michel.for...@michelf.com http://michelf.com/