Re: Destruction Sequence: module and classes defined within
On Tue, 05 Oct 2010 23:25:36 +0200, vano wrote: The code below: module used; import std.stdio; class ClassA { this() { writeln(A ctor); } ~this() { writeln(A dtor); } } static this() { writeln(used.sctor); } static ~this() { writeln(used.sdtor); } void main() { auto a = new ClassA(); } produces the following output (DMD v2.049): used.sctor A ctor used.sdtor A dtor The question is: should the module be allowed to be unloaded before all module-level objects/structures are destructed/unloaded? I'm no expert on this, but I think it has to be that way. Consider this: class Foo { ... } Foo foo; static this() { foo = new Foo; } static ~this() { foo.doStuff(); } So you see, if foo had already been destroyed and garbage collected, my program would have crashed when the module static destructor was run. Thus, I guess, running the garbage collector for the final time has to be one of the last things done on program shutdown, after running all module destructors. -Lars
Initialisation of static immutable arrays
I have a program that uses an immutable array, the contents of which are known at compile time. Thus, ideally, I want it to be placed in the .rodata segment of the program. Firstly, I seem to remember reading that using an array literal in D will always result in a heap allocation. Is this correct? Secondly, if the above is not true, how can I verify that the array in the following piece of code isn't allocated and/or copied anew every time the program runs, or even worse, every time foo() is called? void foo() { static immutable int[3] = [1, 2, 3]; } I know, RTFAsm, but some help with that would be appreciated. ;) Thirdly, intuition tells me that when the array is immutable, the 'static' shouldn't have an effect. But experiments (i.e. printing the adress of the array) indicate that it does. Is there some reason for this, or is it just a shortcoming of the compiler? -Lars
Re: Initialisation of static immutable arrays
On Wed, 06 Oct 2010 10:16:45 +, Lars T. Kyllingstad wrote: static immutable int[3] = [1, 2, 3]; ..should of course be static immutable int[3] a = [1, 2, 3]; -Lars
Re: Associative arrays give compile error
On Tue, 05 Oct 2010 22:02:30 -0400, bearophile bearophileh...@lycos.com wrote: Denis Koroskin: Compute mutable copy and then cast to immutable. Am I missing something? That's possible. But it's an exceptionally dirty thing, I am not sure it works in SafeD. A well designed const system has to offer a more clean solution :-) Do you agree? Casting to immutable is the only way to create such a beast. The best way to ensure as few bugs as possible is to create the object you wish to be immutable in a function, and cast at the end before returning. This at least encapsulates the dirtiness in one function (which would probably be marked @trusted). You can also use assumeUnique (which I'm guessing is there so it can be called in safeD?). -Steve
Re: Initialisation of static immutable arrays
On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad pub...@kyllingen.nospamnet wrote: I have a program that uses an immutable array, the contents of which are known at compile time. Thus, ideally, I want it to be placed in the .rodata segment of the program. Firstly, I seem to remember reading that using an array literal in D will always result in a heap allocation. Is this correct? Yes. There is no way to create an immutable array besides a string in read only memory. Even enums will result in array literals being created on the heap whenever you refer to them (there's a bug related to this somewhere). Secondly, if the above is not true, how can I verify that the array in the following piece of code isn't allocated and/or copied anew every time the program runs, or even worse, every time foo() is called? void foo() { static immutable int[3] = [1, 2, 3]; } Actually, static probably will prevent it from being created every time foo is called. I don't think there's a way to prevent it from being created every time the program is run. I know, RTFAsm, but some help with that would be appreciated. ;) Thirdly, intuition tells me that when the array is immutable, the 'static' shouldn't have an effect. But experiments (i.e. printing the adress of the array) indicate that it does. Is there some reason for this, or is it just a shortcoming of the compiler? Of course. If you realize that the expression [1,2,3] is not immutable, then it makes sense. Another example to help you think about it: void foo(int x) { immutable int[3] = [1,2,x]; } This must be run on every call of foo, because x can vary. BTW, I'm all for making array literals immutable. You can always make runtime-allocated arrays via a library function. -Steve
Re: Initialisation of static immutable arrays
On Wed, 06 Oct 2010 15:39:48 +0400, Steven Schveighoffer schvei...@yahoo.com wrote: BTW, I'm all for making array literals immutable. You can always make runtime-allocated arrays via a library function. -Steve I second that!
Re: Associative arrays give compile error
Steven Schveighoffer: Casting to immutable is the only way to create such a beast. Then maybe we have to improve the language semantics to allow a better solution. See the Transients of Clojure or the larval objects of Java :-) The compiler may need to test (at compile time) that there's only one reference to the AA and its contents, and turn it into immutable. Bye, bearophile
Using the llvm D-bindings
Hi, did anyone have success using the llvm-2.7 D-bindings from the bindings project http://www.dsource.org/projects/bindings on x86_64 linux? I tried so far with ldc, but the compiler chokes about a mere 3570 lines of unresolved symbols when linking with ldc, compiling works fine. Short version: == I think the question boils down to How do I create a D library and link it into a c++ program on x86_64 linux using ldc (or gdc or any_other_D_compiler). Long version: = Here's a snip of the linker error messages I get from ldc: // -- file main.d import llvm.c.Core; void main() { auto context = LLVMGetGlobalContext(); } // -- $ ldc -I=/path/to/llvm-2.7 \ -L=/usr/local/lib/libLLVM{Core,Support,System}.a main.d /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMContextCreate': Core.cpp:(.text+0x57): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMModuleCreateWithName': Core.cpp:(.text+0x13a): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMModuleCreateWithNameInContext': Core.cpp:(.text+0x195): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMSetDataLayout': Core.cpp:(.text+0x240): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::basic_string(char const*, unsigned long, std::allocatorchar const)' Core.cpp:(.text+0x24f): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::assign(std::basic_stringchar, std::char_traitschar, std::allocatorchar const)' Core.cpp:(.text+0x25e): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::_Rep::_S_empty_rep_storage' Core.cpp:(.text+0x294): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::_Rep::_M_destroy(std::allocatorchar const)' [...] After scanning over the error messages, I think it's only operator, delete and std::* symbols that are missing. I also get the same error messages when I try to compile an equivalent C program that uses the llvm-c/* headers with gcc, but it works with g++, so I'm quite sure the problem is the missing c++ runtime, which is nonexistent in ldc. I think there are only two ways to solve this: (1) link the c++ runtime to ldc (I have no clue how to do that or if it's possible) (2) Write a D library using the llvm D-bindings, define a semi-main function as extern(C), and write a c++ wrapper program that links to the D library and does nothing more than calling the semi-main function. The llvm symbols and c++ runtime will then be linked in using g++. Option (2) seems easy, but ldc does not seem to have a linker swith to build libraries, and doing ldc -c myprog.d # produces myprog.o ar -cq myprog.a myprog.o to generate a library from the object file doesn't work because there are still undefined symbols to the main function or the module ctors in there, even when myprog.d doesn't define a main function. I could try to hack those missing functions back in by defining them in the C program, but there must be some simpler way to generate libraries, or am I at a loosing front here? I also consider using other compilers than ldc as an option, but afaik the only other usable compiler might be gdc (is that stable by now?).
Re: Initialisation of static immutable arrays
On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote: On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad pub...@kyllingen.nospamnet wrote: [...] Secondly, if the above is not true, how can I verify that the array in the following piece of code isn't allocated and/or copied anew every time the program runs, or even worse, every time foo() is called? void foo() { static immutable int[3] = [1, 2, 3]; } Actually, static probably will prevent it from being created every time foo is called. I don't think there's a way to prevent it from being created every time the program is run. Does anyone know a way to verify this? (If it is in fact created every time the function runs, I'll change it to a module-level array initialised in a 'static this()' instead.) I know, RTFAsm, but some help with that would be appreciated. ;) Thirdly, intuition tells me that when the array is immutable, the 'static' shouldn't have an effect. But experiments (i.e. printing the adress of the array) indicate that it does. Is there some reason for this, or is it just a shortcoming of the compiler? Of course. If you realize that the expression [1,2,3] is not immutable, then it makes sense. Another example to help you think about it: void foo(int x) { immutable int[3] = [1,2,x]; } This must be run on every call of foo, because x can vary. I don't think that is a very good reason. The compiler could detect the special (and, might I add, common) case where an array literal whose contents are known at compile time is assigned to an immutable variable, and treat it as immutable even though [1,2,3] is formally of type int[]. BTW, I'm all for making array literals immutable. You can always make runtime-allocated arrays via a library function. I completely agree. -Lars
Re: Initialisation of static immutable arrays
On Wed, 06 Oct 2010 16:21:08 +0400, Lars T. Kyllingstad pub...@kyllingen.nospamnet wrote: On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote: On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad pub...@kyllingen.nospamnet wrote: [...] Secondly, if the above is not true, how can I verify that the array in the following piece of code isn't allocated and/or copied anew every time the program runs, or even worse, every time foo() is called? void foo() { static immutable int[3] = [1, 2, 3]; } Actually, static probably will prevent it from being created every time foo is called. I don't think there's a way to prevent it from being created every time the program is run. Does anyone know a way to verify this? (If it is in fact created every time the function runs, I'll change it to a module-level array initialised in a 'static this()' instead.) It's static so it allocates only once. But the following: immutable int[3] = [1, 2, 3]; always allocates, but I see no reason why it should.
Re: Using the llvm D-bindings
On Wed, 06 Oct 2010 16:20:41 +0400, Manuel König manuel...@gmx.net wrote: Hi, did anyone have success using the llvm-2.7 D-bindings from the bindings project http://www.dsource.org/projects/bindings on x86_64 linux? I tried so far with ldc, but the compiler chokes about a mere 3570 lines of unresolved symbols when linking with ldc, compiling works fine. Short version: == I think the question boils down to How do I create a D library and link it into a c++ program on x86_64 linux using ldc (or gdc or any_other_D_compiler). Long version: = Here's a snip of the linker error messages I get from ldc: // -- file main.d import llvm.c.Core; void main() { auto context = LLVMGetGlobalContext(); } // -- $ ldc -I=/path/to/llvm-2.7 \ -L=/usr/local/lib/libLLVM{Core,Support,System}.a main.d /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMContextCreate': Core.cpp:(.text+0x57): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMModuleCreateWithName': Core.cpp:(.text+0x13a): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMModuleCreateWithNameInContext': Core.cpp:(.text+0x195): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMSetDataLayout': Core.cpp:(.text+0x240): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::basic_string(char const*, unsigned long, std::allocatorchar const)' Core.cpp:(.text+0x24f): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::assign(std::basic_stringchar, std::char_traitschar, std::allocatorchar const)' Core.cpp:(.text+0x25e): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::_Rep::_S_empty_rep_storage' Core.cpp:(.text+0x294): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::_Rep::_M_destroy(std::allocatorchar const)' [...] After scanning over the error messages, I think it's only operator, delete and std::* symbols that are missing. I also get the same error messages when I try to compile an equivalent C program that uses the llvm-c/* headers with gcc, but it works with g++, so I'm quite sure the problem is the missing c++ runtime, which is nonexistent in ldc. I think there are only two ways to solve this: (1) link the c++ runtime to ldc (I have no clue how to do that or if it's possible) (2) Write a D library using the llvm D-bindings, define a semi-main function as extern(C), and write a c++ wrapper program that links to the D library and does nothing more than calling the semi-main function. The llvm symbols and c++ runtime will then be linked in using g++. Option (2) seems easy, but ldc does not seem to have a linker swith to build libraries, and doing ldc -c myprog.d # produces myprog.o ar -cq myprog.a myprog.o to generate a library from the object file doesn't work because there are still undefined symbols to the main function or the module ctors in there, even when myprog.d doesn't define a main function. I could try to hack those missing functions back in by defining them in the C program, but there must be some simpler way to generate libraries, or am I at a loosing front here? I also consider using other compilers than ldc as an option, but afaik the only other usable compiler might be gdc (is that stable by now?). You should probably ask LDC guys (irc://irc.freenode.net/ldc)
Re: Initialisation of static immutable arrays
On Wed, 06 Oct 2010 08:21:08 -0400, Lars T. Kyllingstad pub...@kyllingen.nospamnet wrote: On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote: Of course. If you realize that the expression [1,2,3] is not immutable, then it makes sense. Another example to help you think about it: void foo(int x) { immutable int[3] = [1,2,x]; } This must be run on every call of foo, because x can vary. I don't think that is a very good reason. The compiler could detect the special (and, might I add, common) case where an array literal whose contents are known at compile time is assigned to an immutable variable, and treat it as immutable even though [1,2,3] is formally of type int[]. I'm not saying it is a good explanation, but it is why the compiler does it. Any time an array literal occurs anywhere is an allocation. I have never seen a case where the compiler optimizes that out. Given that context, the behavior makes sense. I don't think any allocation should occur here, even if array literals are not made immutable, because that allocation is going to be thrown away immediately. I agree this should be special-cased. I believe there are several bugs on array literals and allocations. -Steve
Re: Using the llvm D-bindings
Am Wed, 06 Oct 2010 16:27:11 +0400 schrieb Denis Koroskin 2kor...@gmail.com: On Wed, 06 Oct 2010 16:20:41 +0400, Manuel König manuel...@gmx.net wrote: Hi, did anyone have success using the llvm-2.7 D-bindings from the bindings project http://www.dsource.org/projects/bindings on x86_64 linux? I tried so far with ldc, but the compiler chokes about a mere 3570 lines of unresolved symbols when linking with ldc, compiling works fine. Short version: == I think the question boils down to How do I create a D library and link it into a c++ program on x86_64 linux using ldc (or gdc or any_other_D_compiler). Long version: = Here's a snip of the linker error messages I get from ldc: // -- file main.d import llvm.c.Core; void main() { auto context = LLVMGetGlobalContext(); } // -- $ ldc -I=/path/to/llvm-2.7 \ -L=/usr/local/lib/libLLVM{Core,Support,System}.a main.d /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMContextCreate': Core.cpp:(.text+0x57): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMModuleCreateWithName': Core.cpp:(.text+0x13a): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMModuleCreateWithNameInContext': Core.cpp:(.text+0x195): undefined reference to `operator new(unsigned long)' /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMSetDataLayout': Core.cpp:(.text+0x240): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::basic_string(char const*, unsigned long, std::allocatorchar const)' Core.cpp:(.text+0x24f): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::assign(std::basic_stringchar, std::char_traitschar, std::allocatorchar const)' Core.cpp:(.text+0x25e): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::_Rep::_S_empty_rep_storage' Core.cpp:(.text+0x294): undefined reference to `std::basic_stringchar, std::char_traitschar, std::allocatorchar ::_Rep::_M_destroy(std::allocatorchar const)' [...] After scanning over the error messages, I think it's only operator, delete and std::* symbols that are missing. I also get the same error messages when I try to compile an equivalent C program that uses the llvm-c/* headers with gcc, but it works with g++, so I'm quite sure the problem is the missing c++ runtime, which is nonexistent in ldc. I think there are only two ways to solve this: (1) link the c++ runtime to ldc (I have no clue how to do that or if it's possible) (2) Write a D library using the llvm D-bindings, define a semi-main function as extern(C), and write a c++ wrapper program that links to the D library and does nothing more than calling the semi-main function. The llvm symbols and c++ runtime will then be linked in using g++. Option (2) seems easy, but ldc does not seem to have a linker swith to build libraries, and doing ldc -c myprog.d # produces myprog.o ar -cq myprog.a myprog.o to generate a library from the object file doesn't work because there are still undefined symbols to the main function or the module ctors in there, even when myprog.d doesn't define a main function. I could try to hack those missing functions back in by defining them in the C program, but there must be some simpler way to generate libraries, or am I at a loosing front here? I also consider using other compilers than ldc as an option, but afaik the only other usable compiler might be gdc (is that stable by now?). You should probably ask LDC guys (irc://irc.freenode.net/ldc) Thanks, I'll try. But I think the development of LDC was put on hold due to lack of time and interest, let's see if I can find someone there :)
Re: Using the llvm D-bindings [solved]
Am Wed, 6 Oct 2010 14:36:16 +0200 schrieb Manuel König manuel...@gmx.net: You should probably ask LDC guys (irc://irc.freenode.net/ldc) Thanks, I'll try. But I think the development of LDC was put on hold due to lack of time and interest, let's see if I can find someone there :) Well, the channel was actually full of people, and the problem was solved quickly. Actually the solution was method (1), linking in the stdc++ lib. For the record, here are some usage instructions for the llvm bindings. I will commit them to the repositority later, but I'll wait a bit and see if you have something to add. Initial setup: == (1) checkout from svn (2) cd /path/to/llvm-2.7 (3) run prebuild.sh, this builds Target.o and Ext.o which have to be passed to the linker. For convenience, these *.o files are also merged into a single library libllvm-c-ext.a. Note: Target.o and Ext.o are usually not needed for the regular llvm c interface. But the D bindings add some extra bindings, because the official c interface just doesn't expose all functionality from the c++ interface. These are implemented as a c++ to c to d bridge (c++ to c is Target.cpp and Ext.cpp, c to d is Target.d and Ext.d). Building your application: == To compile and link a file main.d, run LLVMD=/path/to/llvm-dbindings LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'` ldc -I=$LLVMD \ -L=$LLVMD/{Target,Ext}.o \ $LLVM_LIBS \ -L-ldl -L-lstdc++ -relocation-model=pic \ main.d Parameters: LLVM_LIBS a list of all llvm libraries, formatted for ldc -L=$LLVMD/{Target,Ext}.o only needed when you use Target.d or Ext.d -L-lstdc++links in the c++ standard library (llvm at it's core is c++) -relocation-model=pic necessary for calling code in your app from inside of the llvm vm
Re: Using the llvm D-bindings [solved]
The previous Initial setup description didn't pass the copy paste test, now it's more instructive. The same should work for llvm 2.6 and 2.8, too (yes, 2.8 was just released and the bindings are already there :) Initial setup: == svn co http://svn.dsource.org/projects/bindings/trunk/llvm-2.7 cd llvm-2.7 ./prebuild.sh prebuild.sh builds Target.o and Ext.o which have to be passed to the linker. For convenience, these *.o files are also merged into a single library libllvm-c-ext.a. Target.o and Ext.o are usually not needed for the regular llvm c interface. But the D bindings add some extra bindings, because the official c interface just doesn't expose all functionality from the c++ interface. These are implemented as a c++ to c to d bridge (c++ to c is Target.cpp and Ext.cpp, c to d is Target.d and Ext.d). Building your application: == To compile and link a file main.d, run LLVMD=/path/to/llvm-dbindings LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'` ldc -I=$LLVMD \ $LLVM_LIBS \ -L=$LLVMD/libllvm-c-ext.a \ -L-ldl -L-lstdc++ -relocation-model=pic \ main.d Parameters: LLVM_LIBS a list of all llvm libraries, formatted for ldc -L=$LLVMD/libllvm-c-ext.a only needed when you use Target.d or Ext.d -L-lstdc++links in the c++ standard library (llvm at it's core is c++) -relocation-model=pic necessary for calling code in your app from inside of the llvm vm
Re: Using the llvm D-bindings [solved]
On Wed, 06 Oct 2010 16:57:09 +0200, Manuel König wrote: LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'` typo detected, you need: sed 's/-l/-L-l/g' :)
write to file ... trivial?
This should be trivial. However, I've not found in the documentation (trying both std.stdio and std.file) how to write to a file in the manner here: filename.writefln(%s\t%f, someString, someDouble); ... this merely prints filename to screen ... does not create a data file.
Re: write to file ... trivial?
On Wed, 06 Oct 2010 22:43:42 +0400, Dr. Smith i...@far.out wrote: This should be trivial. However, I've not found in the documentation (trying both std.stdio and std.file) how to write to a file in the manner here: filename.writefln(%s\t%f, someString, someDouble); ... this merely prints filename to screen ... does not create a data file. In your case, foo.bar(args) == bar(foo, args) - that is call Uniform Function Call Syntax, that is: filename.writefln(%s\t%f, someString, someDouble); - writefln(filename, %s\t%f, someString, someDouble); which in turn tries using filename as a format. Try using std.stream. It should be something like this: File file = new File(fileName, FileMode.OutNew); // open file for writing, create new if none exists file.writefln(hello, %s!, world); Not tested but should work.
Re: write to file ... trivial?
Here's a minimal little template (checked): import std.stdio; void main() { auto f = File(outfile.txt, w); f.writefln(%s World, Hello); f.close(); } 2010/10/6 Denis Koroskin 2kor...@gmail.com On Wed, 06 Oct 2010 22:43:42 +0400, Dr. Smith i...@far.out wrote: This should be trivial. However, I've not found in the documentation (trying both std.stdio and std.file) how to write to a file in the manner here: filename.writefln(%s\t%f, someString, someDouble); ... this merely prints filename to screen ... does not create a data file. In your case, foo.bar(args) == bar(foo, args) - that is call Uniform Function Call Syntax, that is: filename.writefln(%s\t%f, someString, someDouble); - writefln(filename, %s\t%f, someString, someDouble); which in turn tries using filename as a format. Try using std.stream. It should be something like this: File file = new File(fileName, FileMode.OutNew); // open file for writing, create new if none exists file.writefln(hello, %s!, world); Not tested but should work.
Re: write to file ... trivial?
Thank you. Indeed, I forgot: auto f = File(outfile.txt, w); Interestingly, this apparently works within a for-loop to overwrite the file on the first iteration and appending otherwise (Should there not be an explicit append arg?): for(int i = 0; i 100; i++) { f.writefln(%s%i, World Hello, i); } f.close(); // f.close outside the loop for efficiency? If someone could point me to the online documentation for this matter, I'd appreciate it. I'd prefer to use this forum for less elementary matters.
Re: write to file ... trivial?
Dr. Smith Wrote: Thank you. Indeed, I forgot: auto f = File(outfile.txt, w); Interestingly, this apparently works within a for-loop to overwrite the file on the first iteration and appending otherwise (Should there not be an explicit append arg?): for(int i = 0; i 100; i++) { f.writefln(%s%i, World Hello, i); } f.close(); // f.close outside the loop for efficiency? If someone could point me to the online documentation for this matter, I'd appreciate it. I'd prefer to use this forum for less elementary matters. auto f = File(name, options); Creates a new File object which, based on the options, opens the file for writing (create and replace), reading (binary or text), or appending. All operations are performed on this open file until closed and reopened. So for your example if you do not wish to append to an open file you can do this Now you can get the same behavior even if you close the File with: for(int i = 0; i 100; i++) { auto f = File(name.txt, a); f.writefln(%s%i, World Hello, i); f.close(); } Notice the a instead of w This is appending to the file when it opens it. Thus the reason the first example has f.close outside the loop is because it is opening the File outside the loop. http://digitalmars.com/d/2.0/phobos/std_file.html