Re: Manually allocating a File

2018-02-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/20/18 9:59 PM, Nicholas Wilson wrote:


FYI, File is a reference counted FILE* so theres not really any point of 
heap allocating it.


More FYI, the reference counted payload is actually allocated on the C 
heap :) So you are wasting a lot of effort to do something that is 
already done.


-Steve


Re: Manually allocating a File

2018-02-20 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, February 21, 2018 02:59:21 Nicholas Wilson via Digitalmars-d-
learn wrote:
> On Tuesday, 20 February 2018 at 15:32:45 UTC, Chris M. wrote:
> > Thanks for the info, that clears things up. Like I said, it was
> > more experimentation rather than me planning to actually use
> > it. Works now with the following modifications.
> >
> > import std.stdio;
> > import core.stdc.stdlib;
> > import std.conv;
> >
> > void main()
> > {
> >
> > auto f = cast(File*) malloc(File.sizeof);
> > emplace!File(f, "test.txt", "r");
> > f.readln.write;
> > free(f);
> >
> > }
> >
> >>> (*f).readln.writeln;
> >>
> >> That * is unnecessary btw, in D you can
> >>
> >> f.readln
> >>
> >> and it will see it is a pointer to struct and dereference it
> >> for you.
> >
> > That's what I had originally, but I put the * in to see if it
> > would help with the original issue and never removed it
>
> FYI, File is a reference counted FILE* so theres not really any
> point of heap allocating it.

And worse, simply calling free does not run the File's destructor, so simply
using malloc to allocate it and free to free is not going to result in File
functioning properly. If someone were going to just use the C API and not
use std.stdio.File, then using malloc and free with FILE might make sense,
but it really doesn't make sense with File.

- Jonathan M Davis



Re: Manually allocating a File

2018-02-20 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 20 February 2018 at 15:32:45 UTC, Chris M. wrote:
Thanks for the info, that clears things up. Like I said, it was 
more experimentation rather than me planning to actually use 
it. Works now with the following modifications.


import std.stdio;
import core.stdc.stdlib;
import std.conv;

void main()
{
auto f = cast(File*) malloc(File.sizeof);
emplace!File(f, "test.txt", "r");
f.readln.write;
free(f);
}


(*f).readln.writeln;


That * is unnecessary btw, in D you can

f.readln

and it will see it is a pointer to struct and dereference it 
for you.


That's what I had originally, but I put the * in to see if it 
would help with the original issue and never removed it


FYI, File is a reference counted FILE* so theres not really any 
point of heap allocating it.


Re: Manually allocating a File

2018-02-20 Thread Chris M. via Digitalmars-d-learn

On Tuesday, 20 February 2018 at 15:18:11 UTC, Adam D. Ruppe wrote:

On Tuesday, 20 February 2018 at 14:56:54 UTC, Chris M. wrote:
I'm doing this mainly for experimentation, but the following 
piece of code gives all sorts of errors.


so important note: this will perform worse than the automatic 
allocation, which just puts it down in-place. You should 
basically never `new` or `malloc` a `File` struct. (in fact, i 
think we should @disable new on it! yes, D can do that!)




auto f = cast(File *) malloc(File.sizeof);
*f = File("test.txt", "r");


Two notes here: 1) it will call the destructor on *f, which is 
uninitialized data and 2) the destructor that actually wants to 
run will have to wait until the GC reaps it, which is also not 
ideal. The segfault you see is in #2 here, though I'm not sure 
exactly what is causing it, could be out-of-order, could be 
some other corruption, idk.


Generally, when manually allocating D objects, first malloc it, 
then copy the `.init` value over, before casting it to the 
other type - do all this as bytes so it doesn't trigger 
postblits, destructors, etc like a real struct. The 
`std.conv.emplace` function from phobos does this and its 
source code can help you see how in a few cases.


Thanks for the info, that clears things up. Like I said, it was 
more experimentation rather than me planning to actually use it. 
Works now with the following modifications.


import std.stdio;
import core.stdc.stdlib;
import std.conv;

void main()
{
auto f = cast(File*) malloc(File.sizeof);
emplace!File(f, "test.txt", "r");
f.readln.write;
free(f);
}


(*f).readln.writeln;


That * is unnecessary btw, in D you can

f.readln

and it will see it is a pointer to struct and dereference it 
for you.


That's what I had originally, but I put the * in to see if it 
would help with the original issue and never removed it





Re: Manually allocating a File

2018-02-20 Thread Uknown via Digitalmars-d-learn

On Tuesday, 20 February 2018 at 14:56:54 UTC, Chris M. wrote:
I'm doing this mainly for experimentation, but the following 
piece of code gives all sorts of errors. Hangs, segfaults or 
prints nothing and exits


import std.stdio;
import core.stdc.stdlib;

void main()
{
auto f = cast(File *) malloc(File.sizeof);
*f = File("test.txt", "r");
(*f).readln.writeln;
// freeing is for chumps
}

I could have sworn I've done something similar recently and it 
worked, unfortunately I can't remember what the case was.


This is what gdb gave me on a segfault

Program received signal SIGSEGV, Segmentation fault.
0x77a56c32 in 
_D2rt5minfo__T17runModuleFuncsRevSQBgQBg11ModuleGroup8runDtorsMFZ9__lambda1ZQCkMFAxPyS6object10ModuleInfoZv ()

   from /usr/lib64/libphobos2.so.0.78

So it looks like it's reaching the end of main. Past that I 
can't tell what's going on. Ideas?


File * is a C standard library type. You mixed the C standard 
library and D standard library in a way that would not work.


The correct way to initialize a File*:

void main()
{
import core.stdc.stdlib;
auto F = fopen("test.txt", "r");
scope_exit(fclose(f));

//Reading from the file:

char[100] str;
fgets([0], s.length, f);
}

Honestly speaking though you should avoid using the C library 
when you can use th D standard library.


You can read more on the C standard library and how to use it 
here:

http://en.cppreference.com/w/c/io


Re: Manually allocating a File

2018-02-20 Thread Uknown via Digitalmars-d-learn

On Tuesday, 20 February 2018 at 15:21:59 UTC, Uknown wrote:

On Tuesday, 20 February 2018 at 14:56:54 UTC, Chris M. wrote:
void main()
[snip]


Never mind, I confused FILE* with File...


Re: Manually allocating a File

2018-02-20 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 20 February 2018 at 14:56:54 UTC, Chris M. wrote:
I'm doing this mainly for experimentation, but the following 
piece of code gives all sorts of errors.


so important note: this will perform worse than the automatic 
allocation, which just puts it down in-place. You should 
basically never `new` or `malloc` a `File` struct. (in fact, i 
think we should @disable new on it! yes, D can do that!)




auto f = cast(File *) malloc(File.sizeof);
*f = File("test.txt", "r");


Two notes here: 1) it will call the destructor on *f, which is 
uninitialized data and 2) the destructor that actually wants to 
run will have to wait until the GC reaps it, which is also not 
ideal. The segfault you see is in #2 here, though I'm not sure 
exactly what is causing it, could be out-of-order, could be some 
other corruption, idk.


Generally, when manually allocating D objects, first malloc it, 
then copy the `.init` value over, before casting it to the other 
type - do all this as bytes so it doesn't trigger postblits, 
destructors, etc like a real struct. The `std.conv.emplace` 
function from phobos does this and its source code can help you 
see how in a few cases.



(*f).readln.writeln;


That * is unnecessary btw, in D you can

f.readln

and it will see it is a pointer to struct and dereference it for 
you.



I could have sworn I've done something similar recently and it 
worked, unfortunately I can't remember what the case was.


With other types, you can do this, but File is designed to be 
used in-place...


Manually allocating a File

2018-02-20 Thread Chris M. via Digitalmars-d-learn
I'm doing this mainly for experimentation, but the following 
piece of code gives all sorts of errors. Hangs, segfaults or 
prints nothing and exits


import std.stdio;
import core.stdc.stdlib;

void main()
{
auto f = cast(File *) malloc(File.sizeof);
*f = File("test.txt", "r");
(*f).readln.writeln;
// freeing is for chumps
}

I could have sworn I've done something similar recently and it 
worked, unfortunately I can't remember what the case was.


This is what gdb gave me on a segfault

Program received signal SIGSEGV, Segmentation fault.
0x77a56c32 in 
_D2rt5minfo__T17runModuleFuncsRevSQBgQBg11ModuleGroup8runDtorsMFZ9__lambda1ZQCkMFAxPyS6object10ModuleInfoZv ()

   from /usr/lib64/libphobos2.so.0.78

So it looks like it's reaching the end of main. Past that I can't 
tell what's going on. Ideas?