errnoEnforce: which imports?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri Jun 29 02:28:04 UTC 2018


On Friday, June 29, 2018 01:25:39 kdevel via Digitalmars-d-learn wrote:
> In https://dlang.org/phobos/std_exception.html#errnoEnforce this
> example is shown:
>
> ---
> auto f = errnoEnforce(fopen("data.txt"));
> auto line = readln(f);
> enforce(line.length); // expect a non-empty line
> ---
>
> I added
>
>     import std.stdio;
>     import std.exception;
>
> and get an error message which reminds me of C++:
>
> zz.d(8): Deprecation: std.stdio.fopen(R1, R2)(R1 name, R2 mode =
> "r") if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1)
>
> || isSomeString!R1) && (isInputRange!R2 &&
>
> isSomeChar!(ElementEncodingType!R2) || isSomeString!R2)) is not
> visible from module zz
> zz.d(8): Error: function std.stdio.fopen!(string, string).fopen
> is not accessible from module zz
> zz.d(9): Error: template std.stdio.readln cannot deduce function
> from argument types !()(shared(_IO_FILE)*), candidates are:
> [...]/dmd2/linux/bin64/../../src/phobos/std/stdio.d(4068):
> std.stdio.readln(S = string)(dchar terminator = '\x0a') if
> (isSomeString!S)
> [...]/dmd2/linux/bin64/../../src/phobos/std/stdio.d(4102):
> std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if
> (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
> [...]/dmd2/linux/bin64/../../src/phobos/std/stdio.d(4109):
> std.stdio.readln(C, R)(ref C[] buf, R terminator) if
> (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&
> isBidirectionalRange!R && is(typeof(terminator.front ==
> (dchar).init)))
> make: *** [zz.o] Error 1
>
> What's wrong here?

It looks like that example is using a private function from std.stdio which
wraps core.stdc.stdio.fopen. It also passes a FILE* to readln, which is
completely wrong. readln as a free function works with std.stdio.stdin and
does not accept a FILE*, whereas readln on std.stdio.File obviously operates
on File, since it's a member function on File. You could use
core.stdc.stdio.fopen to get a FILE and pass it to File's constructor, and
then call readln on the file, but really, that example needs to be
completely redone.

The error message for fopen stems from the fact that it's private, and that
message is longer than it would be otherwise because of an import bug that
was previously fixed but generates a deprecation message for now so as not
to immediately break code. The error messages after that have to do with the
compiler showing you the various overloads of readln that don't match FILE*.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list