Thread overview
Using std.stdio.File in a class
Apr 08, 2014
Spacen Jasset
Apr 08, 2014
Adam D. Ruppe
Apr 08, 2014
Spacen Jasset
Apr 08, 2014
Rene Zwanenburg
Apr 08, 2014
Spacen Jasset
Apr 08, 2014
Adam D. Ruppe
Apr 08, 2014
monarch_dodra
Apr 08, 2014
Spacen Jasset
April 08, 2014
I am trying to use file in a class. It doesn't seem to work. File is a struct. Are you not supposed to new structs anymore? The examples seem to use auto, but that isn't going to work in this situation.

Is File a struct to take advantage of Raii?

import std.stdio;

class X
{
    this()
    {
        f = new File("test2", "wt");
    }

    File f;
}


void main()
{
    X x = new X;
}

C:\temp>dmd file.d && file.exe
file.d(7): Error: constructor std.stdio.File.this (shared(_iobuf)* handle, strin
g name, uint refs = 1u, bool isPopened = false) is not callable using argument t
ypes (File*)

DMD32 D Compiler v2.065
April 08, 2014
On Tuesday, 8 April 2014 at 14:52:02 UTC, Spacen Jasset wrote:
> Are you not supposed to new structs anymore?

Only if they're pointers. new File returns a File*, not a File.

But you shouldn't new a File because then the file won't be automatically closed when it goes out of scope (RAII indeed).

Your code should work if you just take out the new keyword.
April 08, 2014
On Tuesday, 8 April 2014 at 14:53:56 UTC, Adam D. Ruppe wrote:
> On Tuesday, 8 April 2014 at 14:52:02 UTC, Spacen Jasset wrote:
>> Are you not supposed to new structs anymore?
>
> Only if they're pointers. new File returns a File*, not a File.
>
> But you shouldn't new a File because then the file won't be automatically closed when it goes out of scope (RAII indeed).
>
> Your code should work if you just take out the new keyword.

Perhaps the new keyword doesn't do what it used to do? I'll have to check all this out.
April 08, 2014
On Tuesday, 8 April 2014 at 15:08:17 UTC, Spacen Jasset wrote:
> On Tuesday, 8 April 2014 at 14:53:56 UTC, Adam D. Ruppe wrote:
>> On Tuesday, 8 April 2014 at 14:52:02 UTC, Spacen Jasset wrote:
>>> Are you not supposed to new structs anymore?
>>
>> Only if they're pointers. new File returns a File*, not a File.
>>
>> But you shouldn't new a File because then the file won't be automatically closed when it goes out of scope (RAII indeed).
>>
>> Your code should work if you just take out the new keyword.
>
> Perhaps the new keyword doesn't do what it used to do? I'll have to check all this out.

Maybe you're confused with C#? In C# you have to use new for structs too. In D new allocates something on the GC heap.
April 08, 2014
On Tue, 08 Apr 2014 10:52:01 -0400, Spacen Jasset <spacenjasset@mailrazer.com> wrote:

> I am trying to use file in a class. It doesn't seem to work. File is a struct. Are you not supposed to new structs anymore? The examples seem to use auto, but that isn't going to work in this situation.
>
> Is File a struct to take advantage of Raii?
>
> import std.stdio;
>
> class X
> {
>      this()
>      {
>          f = new File("test2", "wt");
>      }
>
>      File f;
> }
>
>
> void main()
> {
>      X x = new X;
> }
>
> C:\temp>dmd file.d && file.exe
> file.d(7): Error: constructor std.stdio.File.this (shared(_iobuf)* handle, strin
> g name, uint refs = 1u, bool isPopened = false) is not callable using argument t
> ypes (File*)
>
> DMD32 D Compiler v2.065

Just a word of caution, I don't think the RAII semantics of File work properly in multithreaded code when the File is destroyed by the GC.

-Steve
April 08, 2014
On Tuesday, 8 April 2014 at 15:18:20 UTC, Steven Schveighoffer wrote:
> Just a word of caution, I don't think the RAII semantics of File work properly in multithreaded code when the File is destroyed by the GC.
>
> -Steve

RAII doesn't work correctly with GC, period.
April 08, 2014
On Tuesday, 8 April 2014 at 15:15:37 UTC, Rene Zwanenburg wrote:
> On Tuesday, 8 April 2014 at 15:08:17 UTC, Spacen Jasset wrote:
>> On Tuesday, 8 April 2014 at 14:53:56 UTC, Adam D. Ruppe wrote:
>>> On Tuesday, 8 April 2014 at 14:52:02 UTC, Spacen Jasset wrote:
>>>> Are you not supposed to new structs anymore?
>>>
>>> Only if they're pointers. new File returns a File*, not a File.
>>>
>>> But you shouldn't new a File because then the file won't be automatically closed when it goes out of scope (RAII indeed).
>>>
>>> Your code should work if you just take out the new keyword.
>>
>> Perhaps the new keyword doesn't do what it used to do? I'll have to check all this out.
>
> Maybe you're confused with C#? In C# you have to use new for structs too. In D new allocates something on the GC heap.

I don't think I am confusing it with C hash. I think it's changed. I found this in some old code I wrote years ago:

scope Stream file = new File(filename);

April 08, 2014
On Tuesday, 8 April 2014 at 15:18:20 UTC, Steven Schveighoffer wrote:
> On Tue, 08 Apr 2014 10:52:01 -0400, Spacen Jasset <spacenjasset@mailrazer.com> wrote:
>
>> I am trying to use file in a class. It doesn't seem to work. File is a struct. Are you not supposed to new structs anymore? The examples seem to use auto, but that isn't going to work in this situation.
>>
>> Is File a struct to take advantage of Raii?
>>
>> import std.stdio;
>>
>> class X
>> {
>>     this()
>>     {
>>         f = new File("test2", "wt");
>>     }
>>
>>     File f;
>> }
>>
>>
>> void main()
>> {
>>     X x = new X;
>> }
>>
>> C:\temp>dmd file.d && file.exe
>> file.d(7): Error: constructor std.stdio.File.this (shared(_iobuf)* handle, strin
>> g name, uint refs = 1u, bool isPopened = false) is not callable using argument t
>> ypes (File*)
>>
>> DMD32 D Compiler v2.065
>
> Just a word of caution, I don't think the RAII semantics of File work properly in multithreaded code when the File is destroyed by the GC.
>
> -Steve

What do you mean by don't work? I can see that it won't be RAII anymore since there is no stack scope. However, I expect it to get closed properly - as and when the containing object is collected, or when you use the scope keyword with a class object.

Is this not so?

April 08, 2014
On Tuesday, 8 April 2014 at 15:52:23 UTC, Spacen Jasset wrote:
> scope Stream file = new File(filename);

That's a std.stream.File which is a class (implementing the Stream interface) which is a different animal from std.stdio.File, which is a struct.
April 08, 2014
On Tue, 08 Apr 2014 11:54:45 -0400, Spacen Jasset <spacenjasset@mailrazer.com> wrote:

> On Tuesday, 8 April 2014 at 15:18:20 UTC, Steven Schveighoffer wrote:
>> Just a word of caution, I don't think the RAII semantics of File work properly in multithreaded code when the File is destroyed by the GC.
>
> What do you mean by don't work? I can see that it won't be RAII anymore since there is no stack scope. However, I expect it to get closed properly - as and when the containing object is collected, or when you use the scope keyword with a class object.
>
> Is this not so?

The reference count inc/dec is not thread-safe, so if the GC collects your object in a thread that is not the original thread, it may be racing with your thread that's simultaneously inc/dec the reference count.

What can you do?

1. Single threaded program.
2. destroy the class deterministically with destroy(x);
3. Ensure the file reference is unique, do not share it with any other objects.

-Steve