Comment #0 by bioinfornatics — 2012-07-30T05:23:01Z
http://dlang.org/phobos/std_stdio.html#readf
why readf do not use reference ? as :
uint readf(Data...)(in char[] format, ref Data data);
it is not possible? I think this little thing could enhance to have a D cohesive syntax. Of course D support pointer but ref is more in D spirit and point C spirit. They are not many phobos function where need a pointer or an address.
Thanks, i hope my talk is not stupid
kind regards
Comment #1 by andrei — 2012-07-30T06:50:18Z
When readf was defined, ref didn't work with variadics. Closing because fixing behavior now would break existing code.
Comment #2 by bearophile_hugs — 2012-07-30T07:01:56Z
(In reply to comment #1)
> When readf was defined, ref didn't work with variadics. Closing because fixing
> behavior now would break existing code.
Maybe a less bug prone and different named function should be added, that uses ref...
Comment #3 by andrei — 2012-07-30T08:11:42Z
Actually it's not that bad - readf is not bug prone because it statically ensures that all of its parameters are pointers. Using pointers is also safe because readf doesn't escape them. Actually I'm reopening this with a different title.
(In reply to Jakub Łabaj from comment #4)
> According to Steven's blog post
> (http://dlang.org/blog/2016/09/28/how-to-write-trusted-code-in-d/) I should
> "never use @trusted on template functions that accept arbitrary types". Is
> the readf case special in this regard?
If readf calls user-defined functions (constructor, assignment) then yes that's a problem. The smoking gun would be an unsafe unittest that passes with the current implementation. Can you write one?
Comment #6 by uaaabbjjkl — 2017-01-18T13:29:26Z
Currently I see one way to break the safety, which is to not pass a real pointer, but a structure with unary '*' overloaded:
@safe unittest
{
struct Unsafe
{
int* x;
ref int opUnary(string s)() if (s == "*")
{
int y;
// int* ptr = &y; // not @safe
return *x;
}
}
static int x;
static Unsafe unsafe;
unsafe.x = &x;
string text = "10";
formattedRead(text, "%d ", unsafe); // called by readf
assert(*unsafe.x == 10);
}
Probably I can't mess up assignment operator nor constructor, because only builtin types are parsable (constrained by function unformatValue). So I think making formattedRead / readf accepting only pointers to builtin types is a way to make them @trusted.
Comment #7 by andrei — 2017-01-19T08:00:43Z
Cool, thanks, then the bug is legit. The fix would be a @safe function with a small @trusted core.
Comment #8 by uaaabbjjkl — 2017-01-19T09:31:32Z
Sorry, I'm not sure what you mean by that - what are the next steps to do here?
Comment #9 by andrei — 2017-01-30T16:55:18Z
(In reply to Jakub Łabaj from comment #8)
> Sorry, I'm not sure what you mean by that - what are the next steps to do
> here?
I think Razvan Nitu has reached out to you on how to go about creating PRs.
Comment #10 by uaaabbjjkl — 2017-01-30T17:08:22Z
I know how to create PRs, I've already created some. What I mean is I'm not sure how you see the solution, e.g. '@safe function with a small @trusted core', could elaborate on this, please?
Comment #11 by andrei — 2017-01-30T17:22:09Z
Oh, sorry. The idea is to leave readf unqualified and let the compiler infer whether it's safe or not.
In this particular case I see there's a simple solution - just add a constraint to it making sure all parameters are pointers. Something like:
uint readf(Data...)(in char[] format, Data data)
if (allSatisfy!(isPointer, Data);
Then the only way to call readf is with pointers, which eliminates the possibility of shenanigans.
Comment #12 by andrei — 2017-01-30T17:22:58Z
@Jakub, what's your github id? thx!
Comment #13 by uaaabbjjkl — 2017-01-30T17:35:40Z
I understand now, thanks!
You can find my profile here: https://github.com/byebye. I've create a simple PR: https://github.com/dlang/phobos/pull/5040 for similar issue involving formattedRead, where I was wondering if I should restrict arguments to pointers. So it seems the solution would be exactly the same in both cases.
Comment #14 by github-bugzilla — 2017-02-02T00:23:37Z
Comment #18 by qs.il.paperinik — 2017-03-17T19:39:16Z
As Andrei pointed out, readf has its signature for historic reasons. Please check out my pull: https://github.com/dlang/phobos/pull/5247 If I'm correct, we can deprecate formattedRead and with it readf with pointers.
Tell me if I'm wrong, but there is no justification to make readf @trusted. It accesses a __gshared global and is not @safe for good reasons.
Comment #19 by andrei — 2017-03-18T07:37:11Z
@Bolpat (In reply to Bolpat from comment #18)
> As Andrei pointed out, readf has its signature for historic reasons. Please
> check out my pull: https://github.com/dlang/phobos/pull/5247 If I'm correct,
> we can deprecate formattedRead and with it readf with pointers.
>
> Tell me if I'm wrong, but there is no justification to make readf @trusted.
> It accesses a __gshared global and is not @safe for good reasons.
Using __gshared is not problematic because the reading primitives are interlocked.
Comment #20 by github-bugzilla — 2017-03-22T12:21:58Z