Topic: P0052R2: unique_resource and fclose


Author: Kazutoshi Satoda <k_satoda@f2.dion.ne.jp>
Date: Wed, 13 Apr 2016 02:42:40 +0900
Raw View
P0052R2 shows these examples in Motivation section.
> void demonstrate_unique_resource_with_stdio() {
>   const std::string filename = "hello.txt";
>   { auto file=make_unique_resource(::fopen(filename.c_str(),"w"),&::fclose);
>     ::fputs("Hello World!\n", file.get());
>     ASSERT(file.get()!= NULL);
>   }
....
>   {
>     auto file = make_unique_resource_checked(::fopen("nonexistingfile.txt", "r"),
>                 (FILE*) NULL, &::fclose);
>     ASSERT_EQUAL((FILE*)NULL, file.get());
>   }

Some questions came in my mind.


1. What is the expected way to handle errors from fclose()?

To apply unique_resource on practical codes, such errors must be
handled. But I can't figure out a clean way to do that. My best idea
so far is to call fclose(file.get()) as the last step of operations
and then call file.release().
  {
    auto file = make_unique_resource_checked(::fopen("...", "w"),
                (FILE*) NULL, &::fclose);
    if (!file.get()) { handle error }
    if (::fputs("Hello World!\n", file.get()) < 0) { handle error }
    if (::fclose(file.get()) != 0) { handle error }
    file.release();
  }
I think repeating "fclose" is bad, and "file.release()" after fclose()
looks odd. Same applies to POSIX close() example.
FYI: https://stackoverflow.com/questions/19056309/not-checking-closes-return-value-how-serious-really


2. Isn't it violating the requirement, as fclose(NULL) is undefined?

There is a requirement on class template unique_resource that says "the
expression d(r) shall be well formed, shall have well-defined behavior".
Instantiating unique_resource with NULL and fclose seems violating this
rule.


3. make_unique_resource_checked() can call d(invalid)?

The effects of make_unique_resource_checked() is specified like this.
> Effects: As if
>   bool mustrelease = bool(r == invalid);
>   auto ur= make_unique_resource(forward<R>(r), forward<D>(d));
>   if(mustrelease) ur.release();
>   return ur;
Since the constructor of unique_resource is specified to calls d(r) on
failure of copying the deleter, it seems possible to call d(invalid) in
that case even if mustrelease is false. Such possibility will be bad for
a deleter that may throw on copy (unlike fclose) and has a strict
requirement on validity of its argument (like fclose).

--
k_satoda

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/570D3390.7040600%40f2.dion.ne.jp.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 12 Apr 2016 11:02:22 -0700
Raw View
On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:
> 1. What is the expected way to handle errors from fclose()?

Sit down and cry. There's no way to recover from an error in fclose(). You've
either leaked a file descriptor or a file handle, or both. You're not allowed to
call fclose again with the same handle.

So, even though fclose can fail, there's nothing you can do about it. I don't
think printing something to the user is useful, as it's information the user
can't act on. Even logging an error may not work. You probably will have to
write code that assumes it doesn't fail.

But if you really need to log an error, you can use your own wrapper function
around fclose that does so.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4951360.flgUacBquX%40tjmaciei-mobl4.

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Tue, 12 Apr 2016 13:16:14 -0500
Raw View
--001a113fe7927073d905304daa4b
Content-Type: text/plain; charset=UTF-8

On 12 April 2016 at 12:42, Kazutoshi Satoda <k_satoda@f2.dion.ne.jp> wrote:

> P0052R2 shows these examples in Motivation section.
> > void demonstrate_unique_resource_with_stdio() {
> >   const std::string filename = "hello.txt";
> >   { auto
> file=make_unique_resource(::fopen(filename.c_str(),"w"),&::fclose);
> >     ::fputs("Hello World!\n", file.get());
> >     ASSERT(file.get()!= NULL);
> >   }
> ...
> >   {
> >     auto file =
> make_unique_resource_checked(::fopen("nonexistingfile.txt", "r"),
> >                 (FILE*) NULL, &::fclose);
> >     ASSERT_EQUAL((FILE*)NULL, file.get());
> >   }
>
> Some questions came in my mind.
>
>
> 1. What is the expected way to handle errors from fclose()?
>

IMO, destructors are merely for cleanup.  If you wish to handle errors, you
need to call the resource releasing method (in this case fclose) explicitly.

When I've done this kind of thing in the past, I've written custom classes
to handle it, as in:

class FileHandle
{
    //...

    friend int fclose(FileHandle& fh) {
        int closed = ::fclose(fh.handle);
        fh.handle = nullptr;
        return closed;
    }

    ~FileHandle() { if (handle) ::fclose(handle); }
private:
    FILE* handle = nullptr;
};

I haven't thought about how much of the implementation I can replace with
unique_resource.  It would be a benefit to do so, as using it would make
FileHandle non-copyable without any additional work.

And there are plenty of situations where it is either impossible to not
release a resource or there is no recovery from not being able to release
resource a resource.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  +1-847-691-1404

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BMVuZeyok%2Byd6COMDdeWNU%3D%2B4CHkas6usDKy72KCjFCrg%40mail.gmail.com.

--001a113fe7927073d905304daa4b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 12 April 2016 at 12:42, Kazutoshi Satoda <span dir=3D"l=
tr">&lt;<a href=3D"mailto:k_satoda@f2.dion.ne.jp" target=3D"_blank">k_satod=
a@f2.dion.ne.jp</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div cl=
ass=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex">P0052R2 shows these exam=
ples in Motivation section.<br>
&gt; void demonstrate_unique_resource_with_stdio() {<br>
&gt;=C2=A0 =C2=A0const std::string filename =3D &quot;hello.txt&quot;;<br>
&gt;=C2=A0 =C2=A0{ auto file=3Dmake_unique_resource(::fopen(filename.c_str(=
),&quot;w&quot;),&amp;::fclose);<br>
&gt;=C2=A0 =C2=A0 =C2=A0::fputs(&quot;Hello World!\n&quot;, file.get());<br=
>
&gt;=C2=A0 =C2=A0 =C2=A0ASSERT(file.get()!=3D NULL);<br>
&gt;=C2=A0 =C2=A0}<br>
....<br>
&gt;=C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0auto file =3D make_unique_resource_checked(::fopen(=
&quot;nonexistingfile.txt&quot;, &quot;r&quot;),<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(FILE*) N=
ULL, &amp;::fclose);<br>
&gt;=C2=A0 =C2=A0 =C2=A0ASSERT_EQUAL((FILE*)NULL, file.get());<br>
&gt;=C2=A0 =C2=A0}<br>
<br>
Some questions came in my mind.<br>
<br>
<br>
1. What is the expected way to handle errors from fclose()?<br></blockquote=
><div><br></div><div>IMO, destructors are merely for cleanup.=C2=A0 If you =
wish to handle errors, you need to call the resource releasing method (in t=
his case fclose) explicitly.</div><div><br></div><div>When I&#39;ve done th=
is kind of thing in the past, I&#39;ve written custom classes to handle it,=
 as in:</div><div><br></div><div><font size=3D"1" face=3D"monospace, monosp=
ace">class FileHandle</font></div><div><font size=3D"1" face=3D"monospace, =
monospace">{</font></div><div><font size=3D"1" face=3D"monospace, monospace=
">=C2=A0 =C2=A0 //...</font></div><div><font size=3D"1" face=3D"monospace, =
monospace"><br></font></div><div><font size=3D"1" face=3D"monospace, monosp=
ace">=C2=A0 =C2=A0 friend int fclose(FileHandle&amp; fh) {</font></div><div=
><font size=3D"1" face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 int closed =3D ::fclose(fh.handle);</font></div><div><font size=3D"1" face=
=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 fh.handle =3D nullptr=
;</font></div><div><font size=3D"1" face=3D"monospace, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 return closed;</font></div><div><font size=3D"1" face=
=3D"monospace, monospace">=C2=A0 =C2=A0 }</font></div><div><font size=3D"1"=
 face=3D"monospace, monospace"><br></font></div><div><font size=3D"1" face=
=3D"monospace, monospace">=C2=A0 =C2=A0 ~FileHandle() { if (handle) ::fclos=
e(handle); }</font></div><div><font size=3D"1" face=3D"monospace, monospace=
">private:</font></div><div><font size=3D"1" face=3D"monospace, monospace">=
=C2=A0 =C2=A0 FILE* handle =3D nullptr;</font></div><div><font size=3D"1" f=
ace=3D"monospace, monospace">};</font></div><div><font size=3D"1" face=3D"m=
onospace, monospace"><br></font></div><div>I haven&#39;t thought about how =
much of the implementation I can replace with unique_resource.=C2=A0 It wou=
ld be a benefit to do so, as using it would make FileHandle non-copyable wi=
thout any additional work.</div><div><br></div><div>And there are plenty of=
 situations where it is either impossible to not release a resource or ther=
e is no recovery from not being able to release resource a resource.</div><=
div>--=C2=A0<br></div></div><div class=3D"gmail_signature"><div dir=3D"ltr"=
><div><div dir=3D"ltr"><div>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mai=
lto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@evilo=
verlord.com</a>&gt; =C2=A0+1-847-691-1404</div></div></div></div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BMVuZeyok%2Byd6COMDdeWNU%3D%2=
B4CHkas6usDKy72KCjFCrg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2B=
MVuZeyok%2Byd6COMDdeWNU%3D%2B4CHkas6usDKy72KCjFCrg%40mail.gmail.com</a>.<br=
 />

--001a113fe7927073d905304daa4b--

.


Author: Kazutoshi Satoda <k_satoda@f2.dion.ne.jp>
Date: Wed, 13 Apr 2016 03:31:02 +0900
Raw View
On 2016/04/13 3:02 +0900, Thiago Macieira wrote:
> On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:
>> 1. What is the expected way to handle errors from fclose()?
>
> Sit down and cry. There's no way to recover from an error in fclose(). You've
> either leaked a file descriptor or a file handle, or both. You're not allowed to
> call fclose again with the same handle.

I know that. But even the program can't recover from the error, it
should report the error, which means possible incompleteness, data loss,
etc... Please read this link.
> FYI: https://stackoverflow.com/questions/19056309/not-checking-closes-return-value-how-serious-really

You will anger if, for example, a file-conversion tool exited without
any error message and with code 0, but, some days (weeks, or months)
later, you find that the output file was incomplete due to a network
problem, disk-full, etc... , won't you?

Sadly I have seen some tools which behave like this. I'm afraid that the
example (or the library) in the proposal may increase such programs. So
I want to be sure that unique_resource is designed to be applicable to
programs that correctly handle errors from fclose.

--
k_satoda

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/570D3EE6.6050104%40f2.dion.ne.jp.

.


Author: Andrew Sandoval <sandoval@netwaysglobal.com>
Date: Tue, 12 Apr 2016 13:48:01 -0500
Raw View
--001a1138e084cc9d9605304e19ad
Content-Type: text/plain; charset=UTF-8

On Tue, Apr 12, 2016 at 1:02 PM, Thiago Macieira <thiago@macieira.org>
wrote:

> On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:
> > 1. What is the expected way to handle errors from fclose()?
>
> Sit down and cry. There's no way to recover from an error in fclose().
> You've
> either leaked a file descriptor or a file handle, or both. You're not
> allowed to
> call fclose again with the same handle.
>
> So, even though fclose can fail, there's nothing you can do about it. I
> don't
> think printing something to the user is useful, as it's information the
> user
> can't act on. Even logging an error may not work. You probably will have to
> write code that assumes it doesn't fail.
>
> But if you really need to log an error, you can use your own wrapper
> function
> around fclose that does so.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
> :) Thank you Thaigo!  I needed a good laugh today! :)  Sorry Kazutoshi, I
am not making light of your concern, but that was funny!  And I really do
have to agree with Thaigo.
-Andrew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJEeERX_i%2BGikyQ1NZ9_HcTK8kqxY-QPwx8x0%3Dx5sKb7s3vi%2Bg%40mail.gmail.com.

--001a1138e084cc9d9605304e19ad
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Tue, Apr 12, 2016 at 1:02 PM, Thiago Macieira <span dir=3D"ltr">&lt;=
<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.or=
g</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On quarta-f=
eira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:<br>
&gt; 1. What is the expected way to handle errors from fclose()?<br>
<br>
</span>Sit down and cry. There&#39;s no way to recover from an error in fcl=
ose(). You&#39;ve<br>
either leaked a file descriptor or a file handle, or both. You&#39;re not a=
llowed to<br>
call fclose again with the same handle.<br>
<br>
So, even though fclose can fail, there&#39;s nothing you can do about it. I=
 don&#39;t<br>
think printing something to the user is useful, as it&#39;s information the=
 user<br>
can&#39;t act on. Even logging an error may not work. You probably will hav=
e to<br>
write code that assumes it doesn&#39;t fail.<br>
<br>
But if you really need to log an error, you can use your own wrapper functi=
on<br>
around fclose that does so.<br>
<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=3D"_b=
lank" rel=3D"noreferrer">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" target=3D"_blank" rel=3D"noreferrer">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
<span><br>
</span></blockquote><div>:) Thank you Thaigo!=C2=A0 I needed a good laugh t=
oday! :)=C2=A0 Sorry Kazutoshi, I am not making light of your concern, but =
that was funny!=C2=A0 And I really do have to agree with Thaigo.<br></div><=
div>-Andrew=C2=A0</div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJEeERX_i%2BGikyQ1NZ9_HcTK8kqxY-QPwx=
8x0%3Dx5sKb7s3vi%2Bg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJEeERX_i%=
2BGikyQ1NZ9_HcTK8kqxY-QPwx8x0%3Dx5sKb7s3vi%2Bg%40mail.gmail.com</a>.<br />

--001a1138e084cc9d9605304e19ad--

.


Author: maurice barnum <dawnandmaurice@gmail.com>
Date: Wed, 13 Apr 2016 20:47:39 -0700
Raw View
On 2016-04-12 11:02 , Thiago Macieira wrote:
> On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:
>> 1. What is the expected way to handle errors from fclose()?
>
> Sit down and cry. There's no way to recover from an error in fclose(). You've
> either leaked a file descriptor or a file handle, or both. You're not allowed to
> call fclose again with the same handle.

I disagree.  I once lost data due to an application that didn't
handle error on close.  Consider a program that reads an existing file
and replaces it with a new version:

   input = fopen(old)
   output = fopen(new)
   magic_filter(input, output)
   fclose(input)
   fclose(output)
   rename(new, old)

If the file system doesn't report some write errors until you attempt to
close the file, which at least one version of NFS did when the user's
space quota was exceeded, you'll lose the original data.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/570F12DB.7050700%40burble.org.

.


Author: Andrew Sandoval <sandoval@netwaysglobal.com>
Date: Thu, 14 Apr 2016 00:19:31 -0500
Raw View
--001a11402b240de35e05306b0a36
Content-Type: text/plain; charset=UTF-8

On Wed, Apr 13, 2016 at 10:47 PM, maurice barnum <dawnandmaurice@gmail.com>
wrote:

> On 2016-04-12 11:02 , Thiago Macieira wrote:
>
>> On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:
>>
>>> 1. What is the expected way to handle errors from fclose()?
>>>
>>
>> Sit down and cry. There's no way to recover from an error in fclose().
>> You've
>> either leaked a file descriptor or a file handle, or both. You're not
>> allowed to
>> call fclose again with the same handle.
>>
>
> I disagree.  I once lost data due to an application that didn't
> handle error on close.  Consider a program that reads an existing file and
> replaces it with a new version:
>
>   input = fopen(old)
>   output = fopen(new)
>   magic_filter(input, output)
>   fclose(input)
>   fclose(output)
>   rename(new, old)
>
> If the file system doesn't report some write errors until you attempt to
> close the file, which at least one version of NFS did when the user's
> space quota was exceeded, you'll lose the original data.
>
>
> And what would you do in that case?  If the user's space quota was
exceeded, how do you handle it?  The point is that it is usually going to
be better to bind fopen and fclose together than to leak the descriptor.
If you are writing code where you know the failure needs to be handled
somehow -- because a situation like this could exist, then you can call
fclose and check for an error and THEN explicitly call release() on the
unique_resource.  You are not forced to wait for the unique_resource
destructor before you can call the clean-up function.  Or you could bypass
the whole problem by calling fsync() and check for errors before you let
the unique_resource call fclose.

If we throw the whole thing out for one scenario where it doesn't fit, we
can throw out the whole standard library.  There are always cases where
something isn't a perfect fit.  In your example, you could use scope_exit
instead of unique_resource and have a lambda that handles errors.  Or
instead of binding fclose to the descriptor, you could bind your own fclose
replacement function that does the error handling.  The fopen/fclose
example is just that, an example.

-Andrew Sandoval

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJEeERVqqz%2BeNepaMdaZBTmgC%2B9N10SwZWaTnVLsUHt47UEkfA%40mail.gmail.com.

--001a11402b240de35e05306b0a36
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Apr 13, 2016 at 10:47 PM, maurice barnum <span dir=3D"ltr">&lt;<a href=
=3D"mailto:dawnandmaurice@gmail.com" target=3D"_blank">dawnandmaurice@gmail=
..com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On 2016-=
04-12 11:02 , Thiago Macieira wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:<b=
r>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
1. What is the expected way to handle errors from fclose()?<br>
</blockquote>
<br>
Sit down and cry. There&#39;s no way to recover from an error in fclose(). =
You&#39;ve<br>
either leaked a file descriptor or a file handle, or both. You&#39;re not a=
llowed to<br>
call fclose again with the same handle.<br>
</blockquote>
<br></span>
I disagree.=C2=A0 I once lost data due to an application that didn&#39;t<br=
>
handle error on close.=C2=A0 Consider a program that reads an existing file=
 and replaces it with a new version:<br>
<br>
=C2=A0 input =3D fopen(old)<br>
=C2=A0 output =3D fopen(new)<br>
=C2=A0 magic_filter(input, output)<br>
=C2=A0 fclose(input)<br>
=C2=A0 fclose(output)<br>
=C2=A0 rename(new, old)<br>
<br>
If the file system doesn&#39;t report some write errors until you attempt t=
o close the file, which at least one version of NFS did when the user&#39;s=
<br>
space quota was exceeded, you&#39;ll lose the original data.<span><br>
<br></span><br></blockquote><div>And what would you do in that case?=C2=A0 =
If the user&#39;s space quota was exceeded, how do you handle it?=C2=A0 The=
 point is that it is usually going to be better to bind fopen and fclose to=
gether than to leak the descriptor.=C2=A0 If you are writing code where you=
 know the failure needs to be handled somehow -- because a situation like t=
his could exist, then you can call fclose and check for an error and THEN e=
xplicitly call release() on the unique_resource.=C2=A0 You are not forced t=
o wait for the=C2=A0unique_resource destructor before you can call the clea=
n-up function.=C2=A0 Or you could bypass the whole problem by calling=C2=A0=
fsync() and check for errors before you let the unique_resource call fclose=
..</div><div><br></div><div>If we throw the whole thing out for one scenario=
 where it doesn&#39;t fit, we can throw out the whole standard library.=C2=
=A0 There are always cases where something isn&#39;t a perfect fit.=C2=A0 I=
n your example, you could use scope_exit instead of unique_resource and hav=
e a lambda that handles errors.=C2=A0 Or instead of binding fclose to the d=
escriptor, you could bind your own fclose replacement function that does th=
e error handling.=C2=A0 The fopen/fclose example is just that, an example.<=
/div><div><br></div><div>-Andrew Sandoval</div><div><br></div><div><br></di=
v><div><br></div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJEeERVqqz%2BeNepaMdaZBTmgC%2B9N10Sw=
ZWaTnVLsUHt47UEkfA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJEeERVqqz%2=
BeNepaMdaZBTmgC%2B9N10SwZWaTnVLsUHt47UEkfA%40mail.gmail.com</a>.<br />

--001a11402b240de35e05306b0a36--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 14 Apr 2016 07:27:01 -0700 (PDT)
Raw View
------=_Part_291_1704279952.1460644021520
Content-Type: multipart/alternative;
 boundary="----=_Part_292_403228124.1460644021521"

------=_Part_292_403228124.1460644021521
Content-Type: text/plain; charset=UTF-8



On Wednesday, April 13, 2016 at 11:47:43 PM UTC-4, maurice barnum wrote:
>
> On 2016-04-12 11:02 , Thiago Macieira wrote:
> > On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda
> wrote:
> >> 1. What is the expected way to handle errors from fclose()?
> >
> > Sit down and cry. There's no way to recover from an error in fclose().
> You've
> > either leaked a file descriptor or a file handle, or both. You're not
> allowed to
> > call fclose again with the same handle.
>
> I disagree.  I once lost data due to an application that didn't
> handle error on close.  Consider a program that reads an existing file
> and replaces it with a new version:
>
>    input = fopen(old)
>    output = fopen(new)
>    magic_filter(input, output)
>    fclose(input)
>    fclose(output)
>    rename(new, old)
>
> If the file system doesn't report some write errors until you attempt to
> close the file, which at least one version of NFS did when the user's
> space quota was exceeded, you'll lose the original data.
>

A while ago, I was wrapping the concept of mapping an OpenGL pointer into a
RAII object (this was before persistent mapped buffers came around).
However, `glUnmapBuffer` has a rarely-seen error on unmapping, which if
present means that the buffer has lost all of its contents. This would
usually only happen in pre-Windows Vista (when GPU memory was not
particularly well controlled) and would happen if you did something like
resize the window while the buffer was mapped.

Rare though this would be, it is still an error that some users would want
to handle. I found the most appropriate way to deal with that is to allow
users to call an equivalent to `unique_ptr::reset` to manually invoke the
unmapping. That function would return the OpenGL error code or whatever.
The actual RAII destructor would simply swallow it.

I think this would be a better solution. Add a function
`scope_exit::reset`, which will call the exit function, returning its
return value. Of course, if the `scope_exit` has already been released, it
should throw an exception (since there is no return value to return).

For those users who are both aware of such errors and want to handle them,
there would be a way to do so. For other users, they let RAII handle it.
This would also allow such functions to report errors via exceptions;
std::terminate happens if an exception gets thrown into the destructor, but
not if it gets thrown into `reset`.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c2132a9e-1880-4202-b40e-0fabbccaadec%40isocpp.org.

------=_Part_292_403228124.1460644021521
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, April 13, 2016 at 11:47:43 PM UTC-4,=
 maurice barnum wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-=
04-12 11:02 , Thiago Macieira wrote:
<br>&gt; On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda=
 wrote:
<br>&gt;&gt; 1. What is the expected way to handle errors from fclose()?
<br>&gt;
<br>&gt; Sit down and cry. There&#39;s no way to recover from an error in f=
close(). You&#39;ve
<br>&gt; either leaked a file descriptor or a file handle, or both. You&#39=
;re not allowed to
<br>&gt; call fclose again with the same handle.
<br>
<br>I disagree. =C2=A0I once lost data due to an application that didn&#39;=
t
<br>handle error on close. =C2=A0Consider a program that reads an existing =
file=20
<br>and replaces it with a new version:
<br>
<br>=C2=A0 =C2=A0input =3D fopen(old)
<br>=C2=A0 =C2=A0output =3D fopen(new)
<br>=C2=A0 =C2=A0magic_filter(input, output)
<br>=C2=A0 =C2=A0fclose(input)
<br>=C2=A0 =C2=A0fclose(output)
<br>=C2=A0 =C2=A0rename(new, old)
<br>
<br>If the file system doesn&#39;t report some write errors until you attem=
pt to=20
<br>close the file, which at least one version of NFS did when the user&#39=
;s
<br>space quota was exceeded, you&#39;ll lose the original data.
<br></blockquote><div><br>A while ago, I was wrapping the concept of mappin=
g an OpenGL pointer into a RAII object (this was before persistent mapped b=
uffers came around). However, `glUnmapBuffer` has a rarely-seen error on un=
mapping, which if present means that the buffer has lost all of its content=
s. This would usually only happen in pre-Windows Vista (when GPU memory was=
 not particularly well controlled) and would happen if you did something li=
ke resize the window while the buffer was mapped.<br><br>Rare though this w=
ould be, it is still an error that some users would want to handle. I found=
 the most appropriate way to deal with that is to allow users to call an eq=
uivalent to `unique_ptr::reset` to manually invoke the unmapping. That func=
tion would return the OpenGL error code or whatever. The actual RAII destru=
ctor would simply swallow it.<br><br>I think this would be a better solutio=
n. Add a function `scope_exit::reset`, which will call the exit function, r=
eturning its return value. Of course, if the `scope_exit` has already been =
released, it should throw an exception (since there is no return value to r=
eturn).<br><br>For those users who are both aware of such errors and want t=
o handle them, there would be a way to do so. For other users, they let RAI=
I handle it. This would also allow such functions to report errors via exce=
ptions; std::terminate happens if an exception gets thrown into the destruc=
tor, but not if it gets thrown into `reset`.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c2132a9e-1880-4202-b40e-0fabbccaadec%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c2132a9e-1880-4202-b40e-0fabbccaadec=
%40isocpp.org</a>.<br />

------=_Part_292_403228124.1460644021521--
------=_Part_291_1704279952.1460644021520--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 14 Apr 2016 07:28:03 -0700 (PDT)
Raw View
------=_Part_163_171564431.1460644083834
Content-Type: multipart/alternative;
 boundary="----=_Part_164_845117779.1460644083835"

------=_Part_164_845117779.1460644083835
Content-Type: text/plain; charset=UTF-8



On Thursday, April 14, 2016 at 1:19:33 AM UTC-4, Andrew Sandoval wrote:
>
> On Wed, Apr 13, 2016 at 10:47 PM, maurice barnum <dawnand...@gmail.com
> <javascript:>> wrote:
>
>> On 2016-04-12 11:02 , Thiago Macieira wrote:
>>
>>> On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:
>>>
>>>> 1. What is the expected way to handle errors from fclose()?
>>>>
>>>
>>> Sit down and cry. There's no way to recover from an error in fclose().
>>> You've
>>> either leaked a file descriptor or a file handle, or both. You're not
>>> allowed to
>>> call fclose again with the same handle.
>>>
>>
>> I disagree.  I once lost data due to an application that didn't
>> handle error on close.  Consider a program that reads an existing file
>> and replaces it with a new version:
>>
>>   input = fopen(old)
>>   output = fopen(new)
>>   magic_filter(input, output)
>>   fclose(input)
>>   fclose(output)
>>   rename(new, old)
>>
>> If the file system doesn't report some write errors until you attempt to
>> close the file, which at least one version of NFS did when the user's
>> space quota was exceeded, you'll lose the original data.
>>
>>
>> And what would you do in that case?  If the user's space quota was
> exceeded, how do you handle it?
>

By not renaming the file, presumably.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5b36b783-1b82-4ffc-9b44-b70264ecfc0b%40isocpp.org.

------=_Part_164_845117779.1460644083835
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, April 14, 2016 at 1:19:33 AM UTC-4, A=
ndrew Sandoval wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote">On Wed, Apr 13, 2016 at 10:47 PM, =
maurice barnum <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"sMcA-v1PBAAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">dawnand...@gmail.com</a>&gt;</span> wrote:<=
br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><span>On 2016-04-12 11:02 , Thiago Maciei=
ra wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:<b=
r>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
1. What is the expected way to handle errors from fclose()?<br>
</blockquote>
<br>
Sit down and cry. There&#39;s no way to recover from an error in fclose(). =
You&#39;ve<br>
either leaked a file descriptor or a file handle, or both. You&#39;re not a=
llowed to<br>
call fclose again with the same handle.<br>
</blockquote>
<br></span>
I disagree.=C2=A0 I once lost data due to an application that didn&#39;t<br=
>
handle error on close.=C2=A0 Consider a program that reads an existing file=
 and replaces it with a new version:<br>
<br>
=C2=A0 input =3D fopen(old)<br>
=C2=A0 output =3D fopen(new)<br>
=C2=A0 magic_filter(input, output)<br>
=C2=A0 fclose(input)<br>
=C2=A0 fclose(output)<br>
=C2=A0 rename(new, old)<br>
<br>
If the file system doesn&#39;t report some write errors until you attempt t=
o close the file, which at least one version of NFS did when the user&#39;s=
<br>
space quota was exceeded, you&#39;ll lose the original data.<span><br>
<br></span><br></blockquote><div>And what would you do in that case?=C2=A0 =
If the user&#39;s space quota was exceeded, how do you handle it?</div></di=
v></div></div></blockquote><div><br>By not renaming the file, presumably.<b=
r></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5b36b783-1b82-4ffc-9b44-b70264ecfc0b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5b36b783-1b82-4ffc-9b44-b70264ecfc0b=
%40isocpp.org</a>.<br />

------=_Part_164_845117779.1460644083835--
------=_Part_163_171564431.1460644083834--

.


Author: Kazutoshi Satoda <k_satoda@f2.dion.ne.jp>
Date: Fri, 15 Apr 2016 10:34:58 +0900
Raw View
On 2016/04/14 14:19 +0900, Andrew Sandoval wrote:
....
>>> On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi Satoda wrote:
>>>> 1. What is the expected way to handle errors from fclose()?
....
> If you are writing code where you know the failure needs to be handled
> somehow -- because a situation like this could exist, then you can call
> fclose and check for an error and THEN explicitly call release() on the
> unique_resource.  You are not forced to wait for the unique_resource
> destructor before you can call the clean-up function.

Use of release() seems having a subtle problem. Here is a quote from
my first post.
>     if (::fclose(file.get()) != 0) { handle error }
>     file.release();
If one give an actual "handle error" as "throw ..." or "return ...",
then the second call of fclose() will occur in the destructor, which
results in UB. To fix such a problem, one should write like this:
    int close_result = ::fclose(file.get());
    file.release();
    if (close_result != 0) { throw ...; }

Use of scope_exit() and lambda will require a similar variable in a
wider scope to hold the result, and will have more syntactic overheads:
    FILE* output = fopen(...)
    if (!output) { throw ... }
    int close_result;
    {
      auto guard = make_scope_exit([&]{ close_result = fclose(output); });
      ...
    }
    if (close_result != 0) { throw ... }

If unique_resource give the return value of d(r) via its member function,
say call_deleter() here, the fixed code can be:
    if (file.call_deleter() != 0) { throw ...; }
The above call_deleter() will have a precondition that the deleter is
not yet called. I'm not sure about how a violation of this precondition
should be treated. Throwing an exception may be better than UB.

Alternatively, by making unique_resource hold the return value of the
deleter, the result may be returned by reset() without a precondition.
The code will be:
    if (file.reset() != 0) { throw ...; }
This means no change (overheads) in common cases where decltype(d(r)) is
void.

Another alternative may be to return the resource from release(), just
like unique_ptr::release(). The code will be:
   if (fclose(file.release()) != 0) { throw ...; }

Aren't these good and possible additions to the proposal?



As you are an author of the paper, could you please answer my question
2 and 3?
> 2. Isn't it violating the requirement, as fclose(NULL) is undefined?
....
> 3. make_unique_resource_checked() can call d(invalid)?
....

I think 2 can be solved by some wording tweaks. But 3 seems a difficult
design issue introduced by the last change.

--
k_satoda

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/57104542.7050005%40f2.dion.ne.jp.

.


Author: maurice barnum <pixi@burble.org>
Date: Fri, 15 Apr 2016 20:28:14 -0700
Raw View
On 2016-04-13 22:19 , Andrew Sandoval wrote:
> On Wed, Apr 13, 2016 at 10:47 PM, maurice barnum
> <dawnandmaurice@gmail.com <mailto:dawnandmaurice@gmail.com>> wrote:
>
>     On 2016-04-12 11:02 , Thiago Macieira wrote:
>
>         On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi
>         Satoda wrote:
>
>             1. What is the expected way to handle errors from fclose()?
>
>
>         Sit down and cry. There's no way to recover from an error in
>         fclose(). You've
>         either leaked a file descriptor or a file handle, or both.
>         You're not allowed to
>         call fclose again with the same handle.
>
>
>     I disagree.  I once lost data due to an application that didn't
>     handle error on close.  Consider a program that reads an existing
>     file and replaces it with a new version:
>
>        input = fopen(old)
>        output = fopen(new)
>        magic_filter(input, output)
>        fclose(input)
>        fclose(output)
>        rename(new, old)
>
>     If the file system doesn't report some write errors until you
>     attempt to close the file, which at least one version of NFS did
>     when the user's
>     space quota was exceeded, you'll lose the original data.
>
>
> And what would you do in that case?  If the user's space quota was
> exceeded, how do you handle it?  The point is that it is usually going

not overwrite the original file, and report an error to the user.

i'm sure there are plenty of examples where that's not the right
call, but when the original file in my email mailbox ...

> If we throw the whole thing out for one scenario where it doesn't fit,
> we can throw out the whole standard library.  There are always cases
> where something isn't a perfect fit.  In your example, you could use
> scope_exit instead of unique_resource and have a lambda that handles
> errors.  Or instead of binding fclose to the descriptor, you could bind
> your own fclose replacement function that does the error handling.  The
> fopen/fclose example is just that, an example.

i was objecting to the assertion that fclose() errors aren't
interesting, not to the overall concept.  another poster (sorry, name
not handy) suggested an API where programs that need to check the result
of a "close" can do so by calling .reset(). i think that's a good idea.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5711B14E.4060901%40burble.org.

.


Author: Andrew Sandoval <sandoval@netwaysglobal.com>
Date: Sat, 16 Apr 2016 11:47:11 -0500
Raw View
--001a1138e0840758fc05309ce120
Content-Type: text/plain; charset=UTF-8

On Fri, Apr 15, 2016 at 10:28 PM, maurice barnum <pixi@burble.org> wrote:

> On 2016-04-13 22:19 , Andrew Sandoval wrote:
>
>> On Wed, Apr 13, 2016 at 10:47 PM, maurice barnum
>> <dawnandmaurice@gmail.com <mailto:dawnandmaurice@gmail.com>> wrote:
>>
>>     On 2016-04-12 11:02 , Thiago Macieira wrote:
>>
>>         On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi
>>         Satoda wrote:
>>
>>             1. What is the expected way to handle errors from fclose()?
>>
>>
>>         Sit down and cry. There's no way to recover from an error in
>>         fclose(). You've
>>         either leaked a file descriptor or a file handle, or both.
>>         You're not allowed to
>>         call fclose again with the same handle.
>>
>>
>>     I disagree.  I once lost data due to an application that didn't
>>     handle error on close.  Consider a program that reads an existing
>>     file and replaces it with a new version:
>>
>>        input = fopen(old)
>>        output = fopen(new)
>>        magic_filter(input, output)
>>        fclose(input)
>>        fclose(output)
>>        rename(new, old)
>>
>>     If the file system doesn't report some write errors until you
>>     attempt to close the file, which at least one version of NFS did
>>     when the user's
>>     space quota was exceeded, you'll lose the original data.
>>
>>
>> And what would you do in that case?  If the user's space quota was
>> exceeded, how do you handle it?  The point is that it is usually going
>>
>
> not overwrite the original file, and report an error to the user.
>
> i'm sure there are plenty of examples where that's not the right
> call, but when the original file in my email mailbox ...
>
> If we throw the whole thing out for one scenario where it doesn't fit,
>> we can throw out the whole standard library.  There are always cases
>> where something isn't a perfect fit.  In your example, you could use
>> scope_exit instead of unique_resource and have a lambda that handles
>> errors.  Or instead of binding fclose to the descriptor, you could bind
>> your own fclose replacement function that does the error handling.  The
>> fopen/fclose example is just that, an example.
>>
>
> i was objecting to the assertion that fclose() errors aren't
> interesting, not to the overall concept.  another poster (sorry, name
> not handy) suggested an API where programs that need to check the result
> of a "close" can do so by calling .reset(). i think that's a good idea.
>
>
I definitely do not have a problem with that.  I need to go back and look
at the current paper to see what if anything would prevent that from
working.
-Andrew Sandoval

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJEeERXgt0O1nD7GtmFUfckvEUtYvf2nJ%2BiwaCE8_zd35EsJvg%40mail.gmail.com.

--001a1138e0840758fc05309ce120
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>On Fri, Apr 15, 2016 at 10:28 PM, maurice barnum <spa=
n dir=3D"ltr">&lt;<a href=3D"mailto:pixi@burble.org" target=3D"_blank">pixi=
@burble.org</a>&gt;</span> wrote:<br></div><div class=3D"gmail_extra"><div =
class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-l=
eft-width:1px;border-left-style:solid"><span>On 2016-04-13 22:19 , Andrew S=
andoval wrote:<br>
</span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;b=
order-left-style:solid"><span>
On Wed, Apr 13, 2016 at 10:47 PM, maurice barnum<br></span><div><div class=
=3D"h5">
&lt;<a href=3D"mailto:dawnandmaurice@gmail.com" target=3D"_blank">dawnandma=
urice@gmail.com</a> &lt;mailto:<a href=3D"mailto:dawnandmaurice@gmail.com" =
target=3D"_blank">dawnandmaurice@gmail.com</a>&gt;&gt; wrote:<br>
<br>
=C2=A0 =C2=A0 On 2016-04-12 11:02 , Thiago Macieira wrote:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 On quarta-feira, 13 de abril de 2016 02:42:40 P=
DT Kazutoshi<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Satoda wrote:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 1. What is the expected way to ha=
ndle errors from fclose()?<br>
<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Sit down and cry. There&#39;s no way to recover=
 from an error in<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(). You&#39;ve<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 either leaked a file descriptor or a file handl=
e, or both.<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 You&#39;re not allowed to<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 call fclose again with the same handle.<br>
<br>
<br>
=C2=A0 =C2=A0 I disagree.=C2=A0 I once lost data due to an application that=
 didn&#39;t<br>
=C2=A0 =C2=A0 handle error on close.=C2=A0 Consider a program that reads an=
 existing<br>
=C2=A0 =C2=A0 file and replaces it with a new version:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0input =3D fopen(old)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0output =3D fopen(new)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0magic_filter(input, output)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0fclose(input)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0fclose(output)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0rename(new, old)<br>
<br>
=C2=A0 =C2=A0 If the file system doesn&#39;t report some write errors until=
 you<br>
=C2=A0 =C2=A0 attempt to close the file, which at least one version of NFS =
did<br>
=C2=A0 =C2=A0 when the user&#39;s<br>
=C2=A0 =C2=A0 space quota was exceeded, you&#39;ll lose the original data.<=
br>
<br>
<br>
And what would you do in that case?=C2=A0 If the user&#39;s space quota was=
<br>
exceeded, how do you handle it?=C2=A0 The point is that it is usually going=
<br>
</div></div></blockquote>
<br>
not overwrite the original file, and report an error to the user.<br>
<br>
i&#39;m sure there are plenty of examples where that&#39;s not the right<br=
>
call, but when the original file in my email mailbox ...<span><br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">
If we throw the whole thing out for one scenario where it doesn&#39;t fit,<=
br>
we can throw out the whole standard library.=C2=A0 There are always cases<b=
r>
where something isn&#39;t a perfect fit.=C2=A0 In your example, you could u=
se<br>
scope_exit instead of unique_resource and have a lambda that handles<br>
errors.=C2=A0 Or instead of binding fclose to the descriptor, you could bin=
d<br>
your own fclose replacement function that does the error handling.=C2=A0 Th=
e<br>
fopen/fclose example is just that, an example.<br>
</blockquote>
<br></span>
i was objecting to the assertion that fclose() errors aren&#39;t<br>
interesting, not to the overall concept.=C2=A0 another poster (sorry, name<=
br>
not handy) suggested an API where programs that need to check the result<br=
>
of a &quot;close&quot; can do so by calling .reset(). i think that&#39;s a =
good idea.<span><br>
</span><br></blockquote><div><br></div><div><div>I definitely do not have a=
 problem with that.=C2=A0 I need to go back and look at the current paper t=
o see what if anything would prevent that from working.</div><div>-Andrew S=
andoval</div>=C2=A0</div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJEeERXgt0O1nD7GtmFUfckvEUtYvf2nJ%2B=
iwaCE8_zd35EsJvg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJEeERXgt0O1nD=
7GtmFUfckvEUtYvf2nJ%2BiwaCE8_zd35EsJvg%40mail.gmail.com</a>.<br />

--001a1138e0840758fc05309ce120--

.


Author: Derek Ross <antiquarktv@gmail.com>
Date: Sun, 17 Apr 2016 10:38:41 -0700 (PDT)
Raw View
------=_Part_145_2099171066.1460914722093
Content-Type: multipart/alternative;
 boundary="----=_Part_146_1119063546.1460914722094"

------=_Part_146_1119063546.1460914722094
Content-Type: text/plain; charset=UTF-8

I think that fclose and fopen are too "low level" to give you any
sophisticated error handling.

A simple solution would be to wrap those functions in a way that will
handle errors, e.g., make "fopen_extra" and "fclose_extra" functions that
will either throw exceptions or write to syslog when an error occurs:


FILE *fopen_extra(const char *path, const char *mode){
  FILE* ret = fopen(path, mode);
  if(!ret)throw runtime_error(string("fopen error ")+strerror(errno));
  return ret;
}

int fclose_extra(FILE* f){
  int ret = fclose(f);
  if(0 != ret)
    syslog(LOG_ERR, "fclose error: %s", strerror(errno));
  return ret;
}

....etc...

auto file = make_unique_resource_checked(
    fopen_extra("...", "w"),
    (FILE*) NULL,
    &fclose_extra);


Then at least you would have a record somewhere when an fclose failed.

----
Derek

On Tuesday, April 12, 2016 at 12:42:57 PM UTC-5, Kazutoshi SATODA wrote:
>
> P0052R2 shows these examples in Motivation section.
> > void demonstrate_unique_resource_with_stdio() {
> >   const std::string filename = "hello.txt";
> >   { auto
> file=make_unique_resource(::fopen(filename.c_str(),"w"),&::fclose);
> >     ::fputs("Hello World!\n", file.get());
> >     ASSERT(file.get()!= NULL);
> >   }
> ...
> >   {
> >     auto file =
> make_unique_resource_checked(::fopen("nonexistingfile.txt", "r"),
> >                 (FILE*) NULL, &::fclose);
> >     ASSERT_EQUAL((FILE*)NULL, file.get());
> >   }
>
> Some questions came in my mind.
>
>
> 1. What is the expected way to handle errors from fclose()?
>
> To apply unique_resource on practical codes, such errors must be
> handled. But I can't figure out a clean way to do that. My best idea
> so far is to call fclose(file.get()) as the last step of operations
> and then call file.release().
>   {
>     auto file = make_unique_resource_checked(::fopen("...", "w"),
>                 (FILE*) NULL, &::fclose);
>     if (!file.get()) { handle error }
>     if (::fputs("Hello World!\n", file.get()) < 0) { handle error }
>     if (::fclose(file.get()) != 0) { handle error }
>     file.release();
>   }
> I think repeating "fclose" is bad, and "file.release()" after fclose()
> looks odd. Same applies to POSIX close() example.
> FYI:
> https://stackoverflow.com/questions/19056309/not-checking-closes-return-value-how-serious-really
>
>
> 2. Isn't it violating the requirement, as fclose(NULL) is undefined?
>
> There is a requirement on class template unique_resource that says "the
> expression d(r) shall be well formed, shall have well-defined behavior".
> Instantiating unique_resource with NULL and fclose seems violating this
> rule.
>
>
> 3. make_unique_resource_checked() can call d(invalid)?
>
> The effects of make_unique_resource_checked() is specified like this.
> > Effects: As if
> >   bool mustrelease = bool(r == invalid);
> >   auto ur= make_unique_resource(forward<R>(r), forward<D>(d));
> >   if(mustrelease) ur.release();
> >   return ur;
> Since the constructor of unique_resource is specified to calls d(r) on
> failure of copying the deleter, it seems possible to call d(invalid) in
> that case even if mustrelease is false. Such possibility will be bad for
> a deleter that may throw on copy (unlike fclose) and has a strict
> requirement on validity of its argument (like fclose).
>
> --
> k_satoda
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/260202df-1b1b-48b3-af80-ae6c0453a5ce%40isocpp.org.

------=_Part_146_1119063546.1460914722094
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I think that fclose and fopen are too &quot;low level&quot=
; to give you any sophisticated error handling. <br><br>A simple solution w=
ould be to wrap those functions in a way that will handle errors, e.g., mak=
e &quot;fopen_extra&quot; and &quot;fclose_extra&quot; functions that will =
either throw exceptions or write to syslog when an error occurs:<br><br><di=
v class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bord=
er-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-=
wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>FILE </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">fopen_extra</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">char</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">path</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">char</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">mode</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">){</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 FILE</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> ret </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fopen</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">path</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> mode</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">if</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(!</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">ret</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #008;" class=3D"styled-by-prettify">throw<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> runtime_er=
ror</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">string</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;fopen error &quot;</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)+</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">strerror</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">errno</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">));</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> ret</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fclose_extr=
a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">FILE</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">){</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> ret </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> fclose</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">if</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">!=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> ret</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0 =C2=A0 syslog</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">LOG_ERR</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;fclose erro=
r: %s&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> strerro=
r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">errno</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> ret</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">etc</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.=
...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> file </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> make_unique_resource_check=
ed</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=
=A0 fopen_extra</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quo=
t;...&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;w&quot;</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">FILE</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">*)</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> NULL</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">fclose_extra</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span></div></code></div><br>Then at least=
 you would have a record somewhere when an fclose failed.<br><br>----<br>De=
rek<br><br>On Tuesday, April 12, 2016 at 12:42:57 PM UTC-5, Kazutoshi SATOD=
A wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">P0052R2 shows these ex=
amples in Motivation section.
<br>&gt; void demonstrate_unique_resource_<wbr>with_stdio() {
<br>&gt; =C2=A0 const std::string filename =3D &quot;hello.txt&quot;;
<br>&gt; =C2=A0 { auto file=3Dmake_unique_resource(::<wbr>fopen(filename.c_=
str(),&quot;w&quot;),&amp;:<wbr>:fclose);
<br>&gt; =C2=A0 =C2=A0 ::fputs(&quot;Hello World!\n&quot;, file.get());
<br>&gt; =C2=A0 =C2=A0 ASSERT(file.get()!=3D NULL);
<br>&gt; =C2=A0 }
<br>...
<br>&gt; =C2=A0 {
<br>&gt; =C2=A0 =C2=A0 auto file =3D make_unique_resource_checked(:<wbr>:fo=
pen(&quot;nonexistingfile.txt&quot;, &quot;r&quot;),
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (FILE*) NU=
LL, &amp;::fclose);
<br>&gt; =C2=A0 =C2=A0 ASSERT_EQUAL((FILE*)NULL, file.get());
<br>&gt; =C2=A0 }
<br>
<br>Some questions came in my mind.
<br>
<br>
<br>1. What is the expected way to handle errors from fclose()?
<br>
<br>To apply unique_resource on practical codes, such errors must be
<br>handled. But I can&#39;t figure out a clean way to do that. My best ide=
a
<br>so far is to call fclose(file.get()) as the last step of operations
<br>and then call file.release().
<br>=C2=A0 {
<br>=C2=A0 =C2=A0 auto file =3D make_unique_resource_checked(:<wbr>:fopen(&=
quot;...&quot;, &quot;w&quot;),
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (FILE*) NULL, &=
amp;::fclose);
<br>=C2=A0 =C2=A0 if (!file.get()) { handle error }
<br>=C2=A0 =C2=A0 if (::fputs(&quot;Hello World!\n&quot;, file.get()) &lt; =
0) { handle error }
<br>=C2=A0 =C2=A0 if (::fclose(file.get()) !=3D 0) { handle error }
<br>=C2=A0 =C2=A0 file.release();
<br>=C2=A0 }
<br>I think repeating &quot;fclose&quot; is bad, and &quot;file.release()&q=
uot; after fclose()
<br>looks odd. Same applies to POSIX close() example.
<br>FYI: <a href=3D"https://stackoverflow.com/questions/19056309/not-checki=
ng-closes-return-value-how-serious-really" target=3D"_blank" rel=3D"nofollo=
w" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\75https%3A%=
2F%2Fstackoverflow.com%2Fquestions%2F19056309%2Fnot-checking-closes-return-=
value-how-serious-really\46sa\75D\46sntz\0751\46usg\75AFQjCNHYgW2wy48qgALKN=
QOK46J88EhOnQ&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.go=
ogle.com/url?q\75https%3A%2F%2Fstackoverflow.com%2Fquestions%2F19056309%2Fn=
ot-checking-closes-return-value-how-serious-really\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNHYgW2wy48qgALKNQOK46J88EhOnQ&#39;;return true;">https://stackove=
rflow.com/<wbr>questions/19056309/not-<wbr>checking-closes-return-value-<wb=
r>how-serious-really</a>
<br>
<br>
<br>2. Isn&#39;t it violating the requirement, as fclose(NULL) is undefined=
?
<br>
<br>There is a requirement on class template unique_resource that says &quo=
t;the
<br>expression d(r) shall be well formed, shall have well-defined behavior&=
quot;.
<br>Instantiating unique_resource with NULL and fclose seems violating this
<br>rule.
<br>
<br>
<br>3. make_unique_resource_checked() can call d(invalid)?
<br>
<br>The effects of make_unique_resource_checked() is specified like this.
<br>&gt; Effects: As if
<br>&gt; =C2=A0 bool mustrelease =3D bool(r =3D=3D invalid);
<br>&gt; =C2=A0 auto ur=3D make_unique_resource(forward&lt;<wbr>R&gt;(r), f=
orward&lt;D&gt;(d));
<br>&gt; =C2=A0 if(mustrelease) ur.release();
<br>&gt; =C2=A0 return ur;
<br>Since the constructor of unique_resource is specified to calls d(r) on
<br>failure of copying the deleter, it seems possible to call d(invalid) in
<br>that case even if mustrelease is false. Such possibility will be bad fo=
r
<br>a deleter that may throw on copy (unlike fclose) and has a strict
<br>requirement on validity of its argument (like fclose).
<br>
<br>--=20
<br>k_satoda
<br></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/260202df-1b1b-48b3-af80-ae6c0453a5ce%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/260202df-1b1b-48b3-af80-ae6c0453a5ce=
%40isocpp.org</a>.<br />

------=_Part_146_1119063546.1460914722094--
------=_Part_145_2099171066.1460914722093--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 17 Apr 2016 20:07:17 -0700 (PDT)
Raw View
------=_Part_1570_1362122007.1460948837439
Content-Type: multipart/alternative;
 boundary="----=_Part_1571_1795020841.1460948837439"

------=_Part_1571_1795020841.1460948837439
Content-Type: text/plain; charset=UTF-8



On Saturday, April 16, 2016 at 12:47:13 PM UTC-4, Andrew Sandoval wrote:
>
> On Fri, Apr 15, 2016 at 10:28 PM, maurice barnum <pi...@burble.org
> <javascript:>> wrote:
>
>> On 2016-04-13 22:19 , Andrew Sandoval wrote:
>>
>>> On Wed, Apr 13, 2016 at 10:47 PM, maurice barnum
>>> <dawnand...@gmail.com <javascript:> <mailto:dawnand...@gmail.com
>>> <javascript:>>> wrote:
>>>
>>>     On 2016-04-12 11:02 , Thiago Macieira wrote:
>>>
>>>         On quarta-feira, 13 de abril de 2016 02:42:40 PDT Kazutoshi
>>>         Satoda wrote:
>>>
>>>             1. What is the expected way to handle errors from fclose()?
>>>
>>>
>>>         Sit down and cry. There's no way to recover from an error in
>>>         fclose(). You've
>>>         either leaked a file descriptor or a file handle, or both.
>>>         You're not allowed to
>>>         call fclose again with the same handle.
>>>
>>>
>>>     I disagree.  I once lost data due to an application that didn't
>>>     handle error on close.  Consider a program that reads an existing
>>>     file and replaces it with a new version:
>>>
>>>        input = fopen(old)
>>>        output = fopen(new)
>>>        magic_filter(input, output)
>>>        fclose(input)
>>>        fclose(output)
>>>        rename(new, old)
>>>
>>>     If the file system doesn't report some write errors until you
>>>     attempt to close the file, which at least one version of NFS did
>>>     when the user's
>>>     space quota was exceeded, you'll lose the original data.
>>>
>>>
>>> And what would you do in that case?  If the user's space quota was
>>> exceeded, how do you handle it?  The point is that it is usually going
>>>
>>
>> not overwrite the original file, and report an error to the user.
>>
>> i'm sure there are plenty of examples where that's not the right
>> call, but when the original file in my email mailbox ...
>>
>> If we throw the whole thing out for one scenario where it doesn't fit,
>>> we can throw out the whole standard library.  There are always cases
>>> where something isn't a perfect fit.  In your example, you could use
>>> scope_exit instead of unique_resource and have a lambda that handles
>>> errors.  Or instead of binding fclose to the descriptor, you could bind
>>> your own fclose replacement function that does the error handling.  The
>>> fopen/fclose example is just that, an example.
>>>
>>
>> i was objecting to the assertion that fclose() errors aren't
>> interesting, not to the overall concept.  another poster (sorry, name
>> not handy) suggested an API where programs that need to check the result
>> of a "close" can do so by calling .reset(). i think that's a good idea.
>>
>>
> I definitely do not have a problem with that.  I need to go back and look
> at the current paper to see what if anything would prevent that from
> working.
> -Andrew Sandoval
>

The only other thing I would suggest (in addition to `reset`) would be some
way to support multiple resets.

That is, under the guidelines I outlined, you cannot call `reset` twice on
the same object. If you try, you get an exception. The reason being that we
don't want to put any requirements on the return type of the function (like
being default constructible). And we don't want the scope guard to have to
store an error code. So it's better to just kill the object.

However, you might be in a situation where some prior code may have reset
the object and you aren't aware of it. This would be for a conditional
reset or something (I am aware that such circumstances are coming
dangerously close to breaking the whole point of the object). The
destructor works fine, but all of the reasons for checking the return value
would still exist.

So you either need:

1. A way to test whether a scope_guard object has been reset (or released
or moved-from, for that matter). `explicit operator bool() {return
execute_on_destruction;}` would be sufficient.

2. A `reset_or` function, in the same vein as `value_or` for `optional`. Of
course, if the return function is a `void` function, things become more
complex.

Personally, I prefer #1. It's much simpler than dealing with the `void`
case for #2. And one could always write a free function to encapsulate #2
using the mechanisms in #1.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1abe298c-266b-4246-b2dc-4befa77fd01a%40isocpp.org.

------=_Part_1571_1795020841.1460948837439
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, April 16, 2016 at 12:47:13 PM UTC-4, =
Andrew Sandoval wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>On Fri, Apr 15, 2016 at 10:28 PM, maurice barnum <span dir=3D=
"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"tMPDtq0SBQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return =
true;">pi...@burble.org</a>&gt;</span> wrote:<br></div><div><div class=3D"g=
mail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:=
1px;border-left-style:solid"><span>On 2016-04-13 22:19 , Andrew Sandoval wr=
ote:<br>
</span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;b=
order-left-style:solid"><span>
On Wed, Apr 13, 2016 at 10:47 PM, maurice barnum<br></span><div><div>
&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"tMPD=
tq0SBQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;=
;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">d=
awnand...@gmail.com</a> &lt;mailto:<a href=3D"javascript:" target=3D"_blank=
" gdf-obfuscated-mailto=3D"tMPDtq0SBQAJ" rel=3D"nofollow" onmousedown=3D"th=
is.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;j=
avascript:&#39;;return true;">dawnand...@gmail.<wbr>com</a>&gt;&gt; wrote:<=
br>
<br>
=C2=A0 =C2=A0 On 2016-04-12 11:02 , Thiago Macieira wrote:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 On quarta-feira, 13 de abril de 2016 02:42:40 P=
DT Kazutoshi<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Satoda wrote:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 1. What is the expected way to ha=
ndle errors from fclose()?<br>
<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Sit down and cry. There&#39;s no way to recover=
 from an error in<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(). You&#39;ve<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 either leaked a file descriptor or a file handl=
e, or both.<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 You&#39;re not allowed to<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 call fclose again with the same handle.<br>
<br>
<br>
=C2=A0 =C2=A0 I disagree.=C2=A0 I once lost data due to an application that=
 didn&#39;t<br>
=C2=A0 =C2=A0 handle error on close.=C2=A0 Consider a program that reads an=
 existing<br>
=C2=A0 =C2=A0 file and replaces it with a new version:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0input =3D fopen(old)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0output =3D fopen(new)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0magic_filter(input, output)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0fclose(input)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0fclose(output)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0rename(new, old)<br>
<br>
=C2=A0 =C2=A0 If the file system doesn&#39;t report some write errors until=
 you<br>
=C2=A0 =C2=A0 attempt to close the file, which at least one version of NFS =
did<br>
=C2=A0 =C2=A0 when the user&#39;s<br>
=C2=A0 =C2=A0 space quota was exceeded, you&#39;ll lose the original data.<=
br>
<br>
<br>
And what would you do in that case?=C2=A0 If the user&#39;s space quota was=
<br>
exceeded, how do you handle it?=C2=A0 The point is that it is usually going=
<br>
</div></div></blockquote>
<br>
not overwrite the original file, and report an error to the user.<br>
<br>
i&#39;m sure there are plenty of examples where that&#39;s not the right<br=
>
call, but when the original file in my email mailbox ...<span><br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">
If we throw the whole thing out for one scenario where it doesn&#39;t fit,<=
br>
we can throw out the whole standard library.=C2=A0 There are always cases<b=
r>
where something isn&#39;t a perfect fit.=C2=A0 In your example, you could u=
se<br>
scope_exit instead of unique_resource and have a lambda that handles<br>
errors.=C2=A0 Or instead of binding fclose to the descriptor, you could bin=
d<br>
your own fclose replacement function that does the error handling.=C2=A0 Th=
e<br>
fopen/fclose example is just that, an example.<br>
</blockquote>
<br></span>
i was objecting to the assertion that fclose() errors aren&#39;t<br>
interesting, not to the overall concept.=C2=A0 another poster (sorry, name<=
br>
not handy) suggested an API where programs that need to check the result<br=
>
of a &quot;close&quot; can do so by calling .reset(). i think that&#39;s a =
good idea.<span><br>
</span><br></blockquote><div><br></div><div><div>I definitely do not have a=
 problem with that.=C2=A0 I need to go back and look at the current paper t=
o see what if anything would prevent that from working.</div><div>-Andrew S=
andoval <br></div></div></div></div></div></blockquote><div><br>The only ot=
her thing I would suggest (in addition to `reset`) would be some way to sup=
port multiple resets.<br><br>That is, under the guidelines I outlined, you =
cannot call `reset` twice on the same object. If you try, you get an except=
ion. The reason being that we don&#39;t want to put any requirements on the=
 return type of the function (like being default constructible). And we don=
&#39;t want the scope guard to have to store an error code. So it&#39;s bet=
ter to just kill the object.<br><br>However, you might be in a situation wh=
ere some prior code may have reset the object and you aren&#39;t aware of i=
t. This would be for a conditional reset or something (I am aware that such=
 circumstances are coming dangerously close to breaking the whole point of =
the object). The destructor works fine, but all of the reasons for checking=
 the return value would still exist.<br><br>So you either need:<br><br>1. A=
 way to test whether a scope_guard object has been reset (or released or mo=
ved-from, for that matter). `explicit operator bool() {return execute_on_de=
struction;}` would be sufficient.<br><br>2. A `reset_or` function, in the s=
ame vein as `value_or` for `optional`. Of course, if the return function is=
 a `void` function, things become more complex.<br><br>Personally, I prefer=
 #1. It&#39;s much simpler than dealing with the `void` case for #2. And on=
e could always write a free function to encapsulate #2 using the mechanisms=
 in #1.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1abe298c-266b-4246-b2dc-4befa77fd01a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1abe298c-266b-4246-b2dc-4befa77fd01a=
%40isocpp.org</a>.<br />

------=_Part_1571_1795020841.1460948837439--
------=_Part_1570_1362122007.1460948837439--

.


Author: Kazutoshi Satoda <k_satoda@f2.dion.ne.jp>
Date: Wed, 20 Apr 2016 10:26:12 +0900
Raw View
On 2016/04/18 2:38 +0900, Derek Ross wrote:
> A simple solution would be to wrap those functions in a way that will
> handle errors, e.g., make "fopen_extra" and "fclose_extra" functions that
> will either throw exceptions or write to syslog when an error occurs:

> int fclose_extra(FILE* f){
>   int ret = fclose(f);
>   if(0 != ret)
>     syslog(LOG_ERR, "fclose error: %s", strerror(errno));
>   return ret;
> }
>
> ...etc...
>
> auto file = make_unique_resource_checked(
>     fopen_extra("...", "w"),
>     (FILE*) NULL,
>     &fclose_extra);
>
>
> Then at least you would have a record somewhere when an fclose failed.

This is an improvement, and there can be cases where this is enough.
But the caller is still unable to change the control flow on the error.
It is the problem.

Please see the preceding post from maurice barnum for example.
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/b74TFYOWRB8/A5Qo5fpKBAAJ

--
k_satoda

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5716DAB4.5000100%40f2.dion.ne.jp.

.