Discussion:
Proposal for a delete expression for local variables
Michael Bruck
2014-10-15 07:14:42 UTC
Permalink
Hello everyone,



I am looking for feedback on the outline for a proposal below. I would like
to know if there is interest in such a feature and any ideas on
improvements.




Regards,

Michael



Deleting local variables
Summary

This proposal introduces a way to end the scope of a variable before its
enclosing block ends.

{

std::string foo, bar;

...

delete local foo, bar;

...

}

Motivation

The “} operator” is powerful but but comes with a pre-defined destruction
order which is not suitable for all applications. In real world programs
the desired scopes of objects are not always cleanly nested but sometimes
overlap in complex ways.

Sometimes objects hold expensive resources and especially with programming
patterns like threading or resumable functions the resources can remain
blocked long after use if other functions in the same block require a long
time to complete.

This leads to programming patterns that try to mitigate this problem in
suboptimal ways. A typical approach looks like:

{

auto file = file_open_rlock("data_snippet");

auto blob = file.fetch_all();

file.close();

auto conn = connect_to_peer("192.128.0.1");

conn.send(blob);

blob.destroy();

auto reply = conn.fetch_reply();

conn.disconnect();

auto file2 = file_create("output");

file2.write(reply);

reply.destroy();

file2.close();

}

There are a number of problems with this solution:

-

The library needs to provide a function that releases expensive
resources in addition to the destructor.
-

The library needs to keep track of the additional state in which
resources are freed but the object not yet destroyed.
-

The user needs to locate such a function and understand its semantics to
see if it really releases enough resources.
-

The neutered object still lingers in some form on the stack until the
end of the scope.
-

The compiler can not diagnose at compile time when such an already
neutered object is used accidentally due to code rewrite etc.
-

Diagnostics and other interactions that are tied to the destruction
occur far removed in time from the time the object actually falls out of
use.


This proposal would allow for the following code:

{

auto file = file_open_rlock("data_snippet");

auto blob = file.fetch_all();

delete local file;

auto conn = connect_to_peer("192.128.0.1");

conn.send(blob);

delete local blob;

auto reply = conn.fetch_reply();

delete local conn;

auto file = file_create("output");

file.write(reply);

delete local file, reply;

}

Details

Unlike the regular delete expression the argument is not a pointer but
rather a list of variable or function parameter names.

Variables in the enclosing scope cannot be deleted from within selection
statements (if, switch), iteration statements (while, do, for), catch
clauses or other conditionally executed code.

When goto crosses delete local in the direction of the program flow then it
deletes the object in the same way as when crossing “}”. When goto passes delete
local it must also pass the point of declaration of the name.

Optional: After delete local the name is free for reuse in a new variable
declaration.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Markus Grech
2014-10-15 07:33:02 UTC
Permalink
Why not just limit the scope by adding an additional pair of {}? Is there
any advantage to using "delete local"?
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-15 08:23:40 UTC
Permalink
Post by Markus Grech
Why not just limit the scope by adding an additional pair of {}? Is there
any advantage to using "delete local"?
With {} you lose the use of auto and your code becomes a bit more verbose.
Later modifications become a nightmare. And you need the additional state
'constructed but not yet initialized'.

I hope I got it right:

{
some_typename_we_never_wanted_to_type_again1 reply;

{
some_typename_we_never_wanted_to_type_again2 conn;

{
some_typename_we_never_wanted_to_type_again3 blob;

{
auto file = file_open_rlock("data_snippet");
blob = file.fetch_all();
}

conn = connect_to_peer("192.128.0.1");
conn.send(blob);
}
reply = conn.fetch_reply();
}

{
auto file = file_create("output");
file.write(reply);
}
}
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Roman Perepelitsa
2014-10-15 08:33:03 UTC
Permalink
Post by Markus Grech
Why not just limit the scope by adding an additional pair of {}? Is there
any advantage to using "delete local"?
The "delete local" construct, unlike an extra pair of {}, works with
function parameters.

void foo(std::string s)
{
bar(std::move(s));
// Make sure we don't use 's' after it's been moved.
// Free resources if it still has any.
delete local s;
...
}

Roman Perepelitsa.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-15 09:06:54 UTC
Permalink
Good point about restricting visibility. One caveat though, the destruction
of s would always be done by the caller upon return unless the function is
inlined. I'll add a clarification for later versions.

Michael
Post by Roman Perepelitsa
Post by Markus Grech
Why not just limit the scope by adding an additional pair of {}? Is there
any advantage to using "delete local"?
The "delete local" construct, unlike an extra pair of {}, works with
function parameters.
void foo(std::string s)
{
bar(std::move(s));
// Make sure we don't use 's' after it's been moved.
// Free resources if it still has any.
delete local s;
...
}
Roman Perepelitsa.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2014-10-15 09:14:30 UTC
Permalink
Post by Michael Bruck
Good point about restricting visibility. One caveat though, the destruction
of s would always be done by the caller upon return unless the function is
inlined. I'll add a clarification for later versions.
This proposal is going to be facing an uphill battle if it uses the
keyword 'delete'.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-15 09:27:20 UTC
Permalink
I am open for suggestions. I only picked something so I could put the
concept into writing.

Michael
Post by Michael Bruck
Post by Michael Bruck
Good point about restricting visibility. One caveat though, the
destruction
Post by Michael Bruck
of s would always be done by the caller upon return unless the function
is
Post by Michael Bruck
inlined. I'll add a clarification for later versions.
This proposal is going to be facing an uphill battle if it uses the
keyword 'delete'.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Andrew Tomazos
2014-10-15 08:36:00 UTC
Permalink
If your classes depend on destructor ordering, then you are doing too much
in destructors, and are better off putting the interesting part of the
destructor into a member function and explicitly calling it. In the
destructor you can check if it has been called and then either error or
call it automatically. The member function will have an expressive name
that helps the reader understand what is going on, rather than hiding it in
a nameless destructor.
-Andrew.
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
Deleting local variables
Summary
This proposal introduces a way to end the scope of a variable before its
enclosing block ends.
{
std::string foo, bar;
...
delete local foo, bar;
...
}
Motivation
The “} operator” is powerful but but comes with a pre-defined destruction
order which is not suitable for all applications. In real world programs
the desired scopes of objects are not always cleanly nested but sometimes
overlap in complex ways.
Sometimes objects hold expensive resources and especially with programming
patterns like threading or resumable functions the resources can remain
blocked long after use if other functions in the same block require a long
time to complete.
This leads to programming patterns that try to mitigate this problem in
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
blob.destroy();
auto reply = conn.fetch_reply();
conn.disconnect();
auto file2 = file_create("output");
file2.write(reply);
reply.destroy();
file2.close();
}
-
The library needs to provide a function that releases expensive
resources in addition to the destructor.
-
The library needs to keep track of the additional state in which
resources are freed but the object not yet destroyed.
-
The user needs to locate such a function and understand its semantics
to see if it really releases enough resources.
-
The neutered object still lingers in some form on the stack until the
end of the scope.
-
The compiler can not diagnose at compile time when such an already
neutered object is used accidentally due to code rewrite etc.
-
Diagnostics and other interactions that are tied to the destruction
occur far removed in time from the time the object actually falls out of
use.
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
delete local file;
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
delete local blob;
auto reply = conn.fetch_reply();
delete local conn;
auto file = file_create("output");
file.write(reply);
delete local file, reply;
}
Details
Unlike the regular delete expression the argument is not a pointer but
rather a list of variable or function parameter names.
Variables in the enclosing scope cannot be deleted from within selection
statements (if, switch), iteration statements (while, do, for), catch
clauses or other conditionally executed code.
When goto crosses delete local in the direction of the program flow then
it deletes the object in the same way as when crossing “}”. When goto
passes delete local it must also pass the point of declaration of the
name.
Optional: After delete local the name is free for reuse in a new variable
declaration.
--
---
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
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-15 09:18:59 UTC
Permalink
I think the proposal addresses a number of drawbacks with that approach. I
think that having a unified method to dispose of these objects without
needing special support in your library has clear advantages.

Michael
Post by Andrew Tomazos
If your classes depend on destructor ordering, then you are doing too much
in destructors, and are better off putting the interesting part of the
destructor into a member function and explicitly calling it. In the
destructor you can check if it has been called and then either error or
call it automatically. The member function will have an expressive name
that helps the reader understand what is going on, rather than hiding it in
a nameless destructor.
-Andrew.
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
Deleting local variables
Summary
This proposal introduces a way to end the scope of a variable before its
enclosing block ends.
{
std::string foo, bar;
...
delete local foo, bar;
...
}
Motivation
The “} operator” is powerful but but comes with a pre-defined destruction
order which is not suitable for all applications. In real world programs
the desired scopes of objects are not always cleanly nested but sometimes
overlap in complex ways.
Sometimes objects hold expensive resources and especially with
programming patterns like threading or resumable functions the resources
can remain blocked long after use if other functions in the same block
require a long time to complete.
This leads to programming patterns that try to mitigate this problem in
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
blob.destroy();
auto reply = conn.fetch_reply();
conn.disconnect();
auto file2 = file_create("output");
file2.write(reply);
reply.destroy();
file2.close();
}
-
The library needs to provide a function that releases expensive
resources in addition to the destructor.
-
The library needs to keep track of the additional state in which
resources are freed but the object not yet destroyed.
-
The user needs to locate such a function and understand its semantics
to see if it really releases enough resources.
-
The neutered object still lingers in some form on the stack until the
end of the scope.
-
The compiler can not diagnose at compile time when such an already
neutered object is used accidentally due to code rewrite etc.
-
Diagnostics and other interactions that are tied to the destruction
occur far removed in time from the time the object actually falls out of
use.
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
delete local file;
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
delete local blob;
auto reply = conn.fetch_reply();
delete local conn;
auto file = file_create("output");
file.write(reply);
delete local file, reply;
}
Details
Unlike the regular delete expression the argument is not a pointer but
rather a list of variable or function parameter names.
Variables in the enclosing scope cannot be deleted from within selection
statements (if, switch), iteration statements (while, do, for), catch
clauses or other conditionally executed code.
When goto crosses delete local in the direction of the program flow then
it deletes the object in the same way as when crossing “}”. When goto
passes delete local it must also pass the point of declaration of the
name.
Optional: After delete local the name is free for reuse in a new
variable declaration.
--
---
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
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Andrew Tomazos
2014-10-15 10:06:49 UTC
Permalink
Sorry, I should have actually read your proposal - specifically I think:

{

auto file = file_open_rlock("data_snippet");

auto blob = file.fetch_all();

file.close();

auto conn = connect_to_peer("192.128.0.1");

conn.send(blob);

blob.destroy();

auto reply = conn.fetch_reply();

conn.disconnect();

auto file2 = file_create("output");

file2.write(reply);

reply.destroy();

file2.close();

}


is more readable than:


{

auto file = file_open_rlock("data_snippet");

auto blob = file.fetch_all();

delete local file;


auto conn = connect_to_peer("192.128.0.1");

conn.send(blob);

delete local blob;

auto reply = conn.fetch_reply();

delete local conn;


auto file = file_create("output");

file.write(reply);

delete local file, reply;

}
Post by Michael Bruck
I think the proposal addresses a number of drawbacks with that approach. I
think that having a unified method to dispose of these objects without
needing special support in your library has clear advantages.
Michael
Post by Andrew Tomazos
If your classes depend on destructor ordering, then you are doing too
much in destructors, and are better off putting the interesting part of the
destructor into a member function and explicitly calling it. In the
destructor you can check if it has been called and then either error or
call it automatically. The member function will have an expressive name
that helps the reader understand what is going on, rather than hiding it in
a nameless destructor.
-Andrew.
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
Deleting local variables
Summary
This proposal introduces a way to end the scope of a variable before its
enclosing block ends.
{
std::string foo, bar;
...
delete local foo, bar;
...
}
Motivation
The “} operator” is powerful but but comes with a pre-defined
destruction order which is not suitable for all applications. In real world
programs the desired scopes of objects are not always cleanly nested but
sometimes overlap in complex ways.
Sometimes objects hold expensive resources and especially with
programming patterns like threading or resumable functions the resources
can remain blocked long after use if other functions in the same block
require a long time to complete.
This leads to programming patterns that try to mitigate this problem in
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
blob.destroy();
auto reply = conn.fetch_reply();
conn.disconnect();
auto file2 = file_create("output");
file2.write(reply);
reply.destroy();
file2.close();
}
-
The library needs to provide a function that releases expensive
resources in addition to the destructor.
-
The library needs to keep track of the additional state in which
resources are freed but the object not yet destroyed.
-
The user needs to locate such a function and understand its
semantics to see if it really releases enough resources.
-
The neutered object still lingers in some form on the stack until
the end of the scope.
-
The compiler can not diagnose at compile time when such an already
neutered object is used accidentally due to code rewrite etc.
-
Diagnostics and other interactions that are tied to the destruction
occur far removed in time from the time the object actually falls out of
use.
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
delete local file;
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
delete local blob;
auto reply = conn.fetch_reply();
delete local conn;
auto file = file_create("output");
file.write(reply);
delete local file, reply;
}
Details
Unlike the regular delete expression the argument is not a pointer but
rather a list of variable or function parameter names.
Variables in the enclosing scope cannot be deleted from within selection
statements (if, switch), iteration statements (while, do, for), catch
clauses or other conditionally executed code.
When goto crosses delete local in the direction of the program flow
then it deletes the object in the same way as when crossing “}”. When
goto passes delete local it must also pass the point of declaration of
the name.
Optional: After delete local the name is free for reuse in a new
variable declaration.
--
---
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
Visit this group at http://groups.google.com/a/isocpp.org/group/std-
proposals/.
--
---
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
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2014-10-15 11:55:59 UTC
Permalink
Post by Michael Bruck
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
Not only is it more readable, it's more correct. Relying on destructors for
side effects demands that they ignore any failures. Explicitly flushing and
closing a file or a connection before it goes out of scope gives a
confirmation of success that implicit destructor cleanup does not. (At
least, that can't safely happen until uncaught_exception gets fixed.)

Likewise, it's cleaner if a destructor can treat an open state as a
failure, and avoid flushing or such side effects for the sake of safety
over convenience.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Pablo Oliva
2014-10-15 13:37:18 UTC
Permalink
How is this different from the discussion labeled "*[std-proposals] Local
variables that overstay their welcome*", by Matthew Fioravante, from last
August?
Post by David Krauss
Post by Michael Bruck
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
Not only is it more readable, it's more correct. Relying on destructors
for side effects demands that they ignore any failures. Explicitly flushing
and closing a file or a connection before it goes out of scope gives a
confirmation of success that implicit destructor cleanup does not. (At
least, that can't safely happen until uncaught_exception gets fixed.)
Likewise, it's cleaner if a destructor can treat an open state as a
failure, and avoid flushing or such side effects for the sake of safety
over convenience.
--
---
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
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Nevin Liber
2014-10-15 14:59:26 UTC
Permalink
Post by Pablo Oliva
How is this different from the discussion labeled "*[std-proposals] Local
variables that overstay their welcome*", by Matthew Fioravante, from last
August?
Also, why doesn't std::experimental::optional meet your needs?
--
Nevin ":-)" Liber <mailto:***@eviloverlord.com> (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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-15 15:11:07 UTC
Permalink
Post by Nevin Liber
How is this different from the discussion labeled "[std-proposals] Local
variables that overstay their welcome", by Matthew Fioravante, from last
August?
Also, why doesn't std::experimental::optional meet your needs?
It requires an extra state variable to know whether it is engaged and
code to check that state for optional destruction.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2014-10-15 15:25:45 UTC
Permalink
Post by Michael Bruck
It requires an extra state variable to know whether it is engaged and
code to check that state for optional destruction.
State variables in guards are indeed unnecessary overhead, but when the
destructor in question is heavyweight I/O, the point is mooted.

Most classes can disengage from everything without the help of optional.
Blobs can be empty, and connections can always disconnect before the object
goes out of scope.

It would be nice to let the compiler know that an object becomes trivially
destructible after a certain point in a scope, because it's been reset or
moved-from. But I've yet to see a case where the destructor really needs to
be advanced before the end-of-scope.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-16 07:31:34 UTC
Permalink
Post by David Krauss
Post by Michael Bruck
It requires an extra state variable to know whether it is engaged and
code to check that state for optional destruction.
State variables in guards are indeed unnecessary overhead, but when the
destructor in question is heavyweight I/O, the point is mooted.
The destructor is not heavyweight. E.g. the file destructor only releases
the lock and underlying OS handles. But I guess you can always argue that
an extra bool isn’t that much in relation to the rest of your code.

Apart from stack use the bool also adds to code size. In the small test
program that I appended below f1() compiles to 432 bytes and f2() to 294
bytes (i686-w64-mingw32-g++.exe -Ofast). Also the construction of optional
is not free.
Post by David Krauss
Most classes can disengage from everything without the help of optional.
Blobs can be empty, and connections can always disconnect before the object
goes out of scope.
Well that is the premise of the first example in the proposal. I listed the
disadvantages I see with that.
Post by David Krauss
It would be nice to let the compiler know that an object becomes trivially
destructible after a certain point in a scope, because it's been reset or
moved-from. But I've yet to see a case where the destructor really needs to
be advanced before the end-of-scope.
That reflects the state of the language which lacks a means to destroy
local objects when the user wants to. As a result the libraries include
otherwise unnecessary code to soft-destroy the object and track this
additional state. The proposal would allow a move beyond that status quo.


#include <boost/optional.hpp>

struct S;
void foo(S *);

struct S
{
int x[64];
S(int);
~S();
};

void f1()
{
boost::optional<S> o1{0};
boost::optional<S> o2{0};

foo(o1.get_ptr());
o1.reset();
foo(o2.get_ptr());
}

/* simulate the behavior of delete local (wrong variable init order though)
*/
void f2()
{
S s2{0};
{
S s1{0};

foo(&s1);
}

foo(&s2);
}
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Nevin Liber
2014-10-15 15:31:07 UTC
Permalink
Post by Michael Bruck
It requires an extra state variable to know whether it is engaged and
code to check that state for optional destruction.
How do you avoid it in code like:

auto a = GetSomething();
if (b)
delete local a;
// Do more stuff...

And if you disallow code like that, what stops the optimizer from
optimizing out the extra state variable in boost::experimental::optional?
--
Nevin ":-)" Liber <mailto:***@eviloverlord.com> (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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-16 07:34:12 UTC
Permalink
Post by Nevin Liber
Post by Michael Bruck
It requires an extra state variable to know whether it is engaged and
code to check that state for optional destruction.
auto a = GetSomething();
if (b)
delete local a;
// Do more stuff...
This would not be valid code under the proposal.

And if you disallow code like that, what stops the optimizer from
Post by Nevin Liber
optimizing out the extra state variable in boost::experimental::optional?
It can do so only in the most simple cases. If any exception can be thrown
after the optional has been reset then the compiler has a hard time seeing
that optimization. (I have attached a small test case in the reply to David
Krause that shows that)

And the compiler can not reuse the stack space of the value inside optional
if its address has been used.

Apart from that use-after-reset() is a runtime issue (get_ptr() returns
nullptr) while use-after-delete-local is a compile-time error.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-15 15:00:29 UTC
Permalink
I had not seen that thread before posting. From what I see there the
proposal focuses on making the name inaccessible while retaining the
destruction mechanism. My primary goal is to destroy the object at the site
of the delete local expression.

Michael
Post by Pablo Oliva
How is this different from the discussion labeled "*[std-proposals] Local
variables that overstay their welcome*", by Matthew Fioravante, from last
August?
Post by David Krauss
Post by Michael Bruck
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
Not only is it more readable, it's more correct. Relying on destructors
for side effects demands that they ignore any failures. Explicitly flushing
and closing a file or a connection before it goes out of scope gives a
confirmation of success that implicit destructor cleanup does not. (At
least, that can't safely happen until uncaught_exception gets fixed.)
Likewise, it's cleaner if a destructor can treat an open state as a
failure, and avoid flushing or such side effects for the sake of safety
over convenience.
--
---
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
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael Bruck
2014-10-15 14:58:19 UTC
Permalink
Post by David Krauss
Post by Michael Bruck
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
Not only is it more readable, it's more correct. Relying on destructors
for side effects demands that they ignore any failures. Explicitly flushing
and closing a file or a connection before it goes out of scope gives a
confirmation of success that implicit destructor cleanup does not. (At
least, that can't safely happen until uncaught_exception gets fixed.)
Likewise, it's cleaner if a destructor can treat an open state as a
failure, and avoid flushing or such side effects for the sake of safety
over convenience.
If I understand it correctly the destructor exception issue could be fixed
by the time this extension is added?
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
o***@gmail.com
2014-10-23 16:49:49 UTC
Permalink
Michael,

I've read your proposal. I think that it is a good one and that it is even
necessary to be implemented one day.

I want to share with you my points of view with the intention to help you
improve it.

So far I know this is very strong related with stack unwinding. Stack works
with LIFO (Last input, last output). The objects are deleted in the inverse
order they were created. For example:

#include<iostream>
using namespace std;

struct A{
unsigned a;
A(unsigned aa):a(aa){};
~A(){
cout<<"deleting "<<a<<endl;
}
};

int main(){
A a(0),b(1),c(2);
}//delete local c,b,a;

What you are proposing is to allow the handling of the stack. Variables
deleted should be pushed out from the stack. You called "}" as operator.

I would call it unwind operator

delete local would be an operator composed by two words. Instead of delete
local, it could be more accurate: unwind operator.

This operator should be able to be overloaded with and without specific
arguments.

void operator unwind(){}
void operator unwind(int a,int b){}

int main(){
string a;
unwind a;
string b;
unwind(0,1)b;
}

(Every time that the stack unwinds implicitly a variable or object, the
operator without specific arguments would be called if present).

For example:

{
string a;
}//implicit call to string::operator unwind() if present

I think that even with conditional unwindings the code should be compiled,
only the operator should behaves different.

For example (without conditional unwindings):

int main(){
string a;//use 0x01
unwind a;//free 0x01
string b;//use 0x01
unwind b;//free 0x01
string c;//use 0x01
}//implicit unwind c and free 0x01

With conditional unwindings:

int main(){
string a;//use 0x01
if(condition)unwind a;//destroy the object, call the unwind operator if
present and remove 'a' from stack
string b;//use 0x02
b=a;//To read an unwinded variable should cause undefined behaviour
unwind b;//free 0x02
string c;//use 0x02
}//unwind c and free 0x02

It is important to also consider the *return* and *throw* keywords in your
proposal.

int main(){
string a;
string b;
string c;
unwind a;
throw 0;//implicit unwind of c and b
return 0;//implicit unwind of c and b
}

You wrote:

delete local file, reply;


I think that this would also be a good syntax for the *delete* and
*delete[]* operators:

delete[]a,b,c,d;

But this is not possible because the comma operator has other purpose, for
example:

delete[]a=a-1,a,
delete[]b=b+5,b,
delete[]c=c*3,c,
delete[]--d,d;

The comma operator has the purpose to help the value to be calculated and
it will always be considered only the most right expression, so:

delete[]a,b,c,d;

Only deletes d;

So I think that insted of:

delete local file,replay;

It should be:

delete local file,delete local replay;

Or:

unwind file,unwind replay;

Regards,

PF, ncomputers
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
Deleting local variables
Summary
This proposal introduces a way to end the scope of a variable before its
enclosing block ends.
{
std::string foo, bar;
...
delete local foo, bar;
...
}
Motivation
The “} operator” is powerful but but comes with a pre-defined destruction
order which is not suitable for all applications. In real world programs
the desired scopes of objects are not always cleanly nested but sometimes
overlap in complex ways.
Sometimes objects hold expensive resources and especially with programming
patterns like threading or resumable functions the resources can remain
blocked long after use if other functions in the same block require a long
time to complete.
This leads to programming patterns that try to mitigate this problem in
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
blob.destroy();
auto reply = conn.fetch_reply();
conn.disconnect();
auto file2 = file_create("output");
file2.write(reply);
reply.destroy();
file2.close();
}
-
The library needs to provide a function that releases expensive
resources in addition to the destructor.
-
The library needs to keep track of the additional state in which
resources are freed but the object not yet destroyed.
-
The user needs to locate such a function and understand its semantics
to see if it really releases enough resources.
-
The neutered object still lingers in some form on the stack until the
end of the scope.
-
The compiler can not diagnose at compile time when such an already
neutered object is used accidentally due to code rewrite etc.
-
Diagnostics and other interactions that are tied to the destruction
occur far removed in time from the time the object actually falls out of
use.
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
delete local file;
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
delete local blob;
auto reply = conn.fetch_reply();
delete local conn;
auto file = file_create("output");
file.write(reply);
delete local file, reply;
}
Details
Unlike the regular delete expression the argument is not a pointer but
rather a list of variable or function parameter names.
Variables in the enclosing scope cannot be deleted from within selection
statements (if, switch), iteration statements (while, do, for), catch
clauses or other conditionally executed code.
When goto crosses delete local in the direction of the program flow then
it deletes the object in the same way as when crossing “}”. When goto
passes delete local it must also pass the point of declaration of the
name.
Optional: After delete local the name is free for reuse in a new variable
declaration.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@ncomputers.org
2014-10-23 16:58:24 UTC
Permalink
c***@ncomputers.org
2014-10-24 16:14:39 UTC
Permalink
Michael,

I've been thinking about this topic.

I've also a new idea:

Propose a *push* operator.

*Delete local* and also *unwind* and can be called *pop*.

It could be useful to have overloadable *push* and *pop* operators.

void operator push(){}
void operator pop(){}

void operator push(specific_arguments){}
void operator pop(specific_arguments){}

{
unsigned a;//implicit push
pop a;
unsigned a;
pop a;
push a;
a=0;
pop (arguments) a;
push (arguments) a;
a=1;
}//implicit pop

This could be useful to make distinctions for objcts created with the new
operator and objects created in a fixed way.

PF, ncomputers.org

Am Donnerstag, 23. Oktober 2014 11:58:24 UTC-5 schrieb
Post by o***@gmail.com
Michael,
I've read your proposal. I think that it is a good one and that it is even
necessary to be implemented one day.
I want to share with you my points of view with the intention to help you
improve it.
So far I know this is very strong related with stack unwinding. Stack
works with LIFO (Last input, last output). The objects are deleted in the
#include<iostream>
using namespace std;
struct A{
unsigned a;
A(unsigned aa):a(aa){};
~A(){
cout<<"deleting "<<a<<endl;
}
};
int main(){
A a(0),b(1),c(2);
}//delete local c,b,a;
What you are proposing is to allow the handling of the stack. Deleted
variables should be pushed out from the stack. You called "}" as operator.
I would call it unwind operator
delete local would be an operator composed by two words. Instead of delete
local, it could be more accurate: unwind operator.
This operator should be able to be overloaded with and without specific
arguments.
void operator unwind(){}
void operator unwind(int a,int b){}
int main(){
string a;
unwind a;
string b;
unwind(0,1)b;
}
(Every time that the stack unwinds implicitly a variable or object, the
operator without specific arguments would be called if present).
{
string a;
}//implicit call to string::operator unwind() if present
I think that even with conditional unwindings the code should be compiled,
only that the operator should behave different.
i
nt main(){
string a;//use 0x01
unwind a;//free 0x01
string b;//use 0x01
unwind b;//free 0x01
string c;//use 0x01
}//implicit unwind c and free 0x01
int main(){
string a;//use 0x01
if(condition)unwind a;//destroy the object, call the unwind operator
if present and remove 'a' from stack
string b;//use 0x02
b=a;//To read an unwinded variable should cause undefined behaviour
unwind b;//free 0x02
string c;//use 0x02
}//unwind c and free 0x02
It is important to also consider the* return* and *throw* keywords in
your proposal.
int main(){
string a;
string b;
string c;
unwind a;
throw 0;//implicit unwind of c and b
return 0;//implicit unwind of c and b
}
delete local file, reply;
I think that this would also be a good syntax for the *delete* and
delete[]a,b,c,d;
But this is not possible because the comma operator has other purpose, for
delete[]a=a-1,a,
delete[]b=b+5,b,
delete[]c=c*3,c,
delete[]--d,d;
The comma operator has the purpose to help the value to be calculated and
delete[]a,b,c,d;
Only deletes d;
delete local file,replay;
delete local file,delete local replay;
unwind file,unwind replay;
When goto crosses delete local in the direction of the program flow then
it deletes the object in the same way as when crossing “}”. When goto
passes delete local it must also pass the point of declaration of the
name.
Can you write me please an example?
Regards,
PF, ncomputers
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
Deleting local variables
Summary
This proposal introduces a way to end the scope of a variable before its
enclosing block ends.
{
std::string foo, bar;
...
delete local foo, bar;
...
}
Motivation
The “} operator” is powerful but but comes with a pre-defined destruction
order which is not suitable for all applications. In real world programs
the desired scopes of objects are not always cleanly nested but sometimes
overlap in complex ways.
Sometimes objects hold expensive resources and especially with programming
patterns like threading or resumable functions the resources can remain
blocked long after use if other functions in the same block require a long
time to complete.
This leads to programming patterns that try to mitigate this problem in
{
auto file = file_open_rlock("data_snippet");
auto blob = file.fetch_all();
file.close();
auto conn = connect_to_peer("192.128.0.1");
conn.send(blob);
blob.destroy();
auto reply = conn.fetch_reply();
conn.disconnect();
auto file2 = file_create("output");
file2.write(reply);
reply.destroy();
file2.close();
}
-
The library needs to provide a function that releases expensive
resources in addition to the destructor.
-
The library needs to keep track of the additional state in which
resources are freed but the object not yet destroyed.
-
The user needs to locate such a function and understand its semantics
to see if it really releases enough resources.
-
The neutered object still lingers in some form on the stack until the
end of the scope.
-
The compiler can not diagnose at compile time when such an already
neutered object is used accidentally due to code rewrite etc.
-
Diagnostics and other interactions that are tied to the destruction
occur far removed in time from the time the object actually falls out of
use.
{
auto file = file_open_rlock("data_snippet");
au
...
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@cea.fr
2014-10-23 17:59:48 UTC
Permalink
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
I am not so fond of the idea, especially because we have been heavily
trained to understand and use the consequences of "operator }". This
created an empirical rule, according to which (if you forbid yourself to
"delete" pointers explicitly and respect the RAII principles) all variables
are alive and valid until the end of the scope they were declared in. It
would make code harder to read for me (and, I suppose, a bunch of other
people).
That being said, a similar situation arises with features that are actually
part of the current C++ standard. I am thinking in particular about those
people who refuse to use multiple return statements in a function. The
argument is that it breaks the empirical rule they imposed to themselves
that a function has only one end point. It breaks the flow of the program,
hence they find it less readable (I am *not* one of those). Same thing with
people that refuse to use goto, for similar reasons (I *am* one of those).
It's a matter of taste really, because 1) the standard is written so that
using these features has no undesirable side effects, and 2) in fact you
can write optimal code without multiple return statements, and you can
write optimal without goto. Much like you can write optimal code without
your proposal :

{
auto reply = []() {
auto conn = []() {
auto blob = []() {
auto file = file_open_rlock("data_snippet");
return file.fetch_all();
}();

auto c = connect_to_peer("192.128.0.1");
c.send(blob);
return c;
}();

return conn.fetch_reply();
}();

auto file = file_create("output");
file.write(reply);
}

So what you are proposing is a cosmetic change (except for the special case
of function arguments, which was pointed out by Roman Perepelitsa, but I
doubt it is really useful).

I would say the points to analyze are therefore making sure that: 1) you
introduce no nasty side effects, 2) it will not make it easier for
unexperienced programmers to make mistakes, and 3) the new syntax is
clearer enough that it counter balances the increase in language complexity
(remember that this feature will have to be taught to people at some
points, think about Scott Meyer).

Although it seems at first sight that the proposal passes point 1) above,
it seems to me that this feature would only be used in very peculiar
situations, and I don't think it would be wise to use it as a general
programming habit. The problem is that it might get abused of by students,
or people coming from the C world who still have to learn that "operator }"
can do most of the job for them. My impression is therefore that it fails
point 2) and 3).
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@ncomputers.org
2014-10-23 18:20:45 UTC
Permalink
Post by c***@cea.fr
So what you are proposing is a cosmetic change (except for the special
case of function arguments, which was pointed out by Roman Perepelitsa, but
I doubt it is really useful).
I would say the points to analyze are therefore making sure that: 1) you
introduce no nasty side effects, 2) it will not make it easier for
unexperienced programmers to make mistakes, and 3) the new syntax is
clearer enough that it counter balances the increase in language complexity
(remember that this feature will have to be taught to people at some
points, think about Scott Meyer).
I don't think that it is only a cosmetic change.

2) Inexperienced programmers usually don't know what stack unwinding is.
The most probably is that they won't use it.

3) I think that it would be easier to explain "operator }" with an
"operator unwind".

{
unsinged a;
unsigned b;
}//unwind b, unwind a;

{
unsigned a;
throw 0;//unwind a;
unsigned b;
}//if reached, unwind b;

{
unsigned a;
return 0;//unwind a;
unsigned b;
}//if reached, unwind b;


{
unsigned a;
unwind b;
unsigned a;
unwind a;
}//unwind nothing

PF, ncomputers
Post by c***@cea.fr
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
I am not so fond of the idea, especially because we have been heavily
trained to understand and use the consequences of "operator }". This
created an empirical rule, according to which (if you forbid yourself to
"delete" pointers explicitly and respect the RAII principles) all variables
are alive and valid until the end of the scope they were declared in. It
would make code harder to read for me (and, I suppose, a bunch of other
people).
That being said, a similar situation arises with features that are
actually part of the current C++ standard. I am thinking in particular
about those people who refuse to use multiple return statements in a
function. The argument is that it breaks the empirical rule they imposed to
themselves that a function has only one end point. It breaks the flow of
the program, hence they find it less readable (I am *not* one of those).
Same thing with people that refuse to use goto, for similar reasons (I
*am* one of those). It's a matter of taste really, because 1) the
standard is written so that using these features has no undesirable side
effects, and 2) in fact you can write optimal code without multiple return
statements, and you can write optimal without goto. Much like you can write
{
auto reply = []() {
auto conn = []() {
auto blob = []() {
auto file = file_open_rlock("data_snippet");
return file.fetch_all();
}();
auto c = connect_to_peer("192.128.0.1");
c.send(blob);
return c;
}();
return conn.fetch_reply();
}();
auto file = file_create("output");
file.write(reply);
}
So what you are proposing is a cosmetic change (except for the special
case of function arguments, which was pointed out by Roman Perepelitsa, but
I doubt it is really useful).
I would say the points to analyze are therefore making sure that: 1) you
introduce no nasty side effects, 2) it will not make it easier for
unexperienced programmers to make mistakes, and 3) the new syntax is
clearer enough that it counter balances the increase in language complexity
(remember that this feature will have to be taught to people at some
points, think about Scott Meyer).
Although it seems at first sight that the proposal passes point 1) above,
it seems to me that this feature would only be used in very peculiar
situations, and I don't think it would be wise to use it as a general
programming habit. The problem is that it might get abused of by students,
or people coming from the C world who still have to learn that "operator }"
can do most of the job for them. My impression is therefore that it fails
point 2) and 3).
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
dgutson .
2014-10-24 03:30:53 UTC
Permalink
Post by c***@ncomputers.org
Post by c***@cea.fr
So what you are proposing is a cosmetic change (except for the special
case of function arguments, which was pointed out by Roman Perepelitsa, but
I doubt it is really useful).
I would say the points to analyze are therefore making sure that: 1) you
introduce no nasty side effects, 2) it will not make it easier for
unexperienced programmers to make mistakes, and 3) the new syntax is clearer
enough that it counter balances the increase in language complexity
(remember that this feature will have to be taught to people at some points,
think about Scott Meyer).
I don't think that it is only a cosmetic change.
2) Inexperienced programmers usually don't know what stack unwinding is. The
most probably is that they won't use it.
3) I think that it would be easier to explain "operator }" with an "operator
unwind".
{
unsinged a;
unsigned b;
}//unwind b, unwind a;
{
unsigned a;
throw 0;//unwind a;
unsigned b;
}//if reached, unwind b;
{
unsigned a;
return 0;//unwind a;
unsigned b;
}//if reached, unwind b;
{
unsigned a;
unwind b;
unsigned a;
unwind a;
}//unwind nothing
I don't see any need of special operator since this can be achieved
with 'optional':
http://pastebin.com/Qnba9gv8
Post by c***@ncomputers.org
PF, ncomputers
Post by c***@cea.fr
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
I am not so fond of the idea, especially because we have been heavily
trained to understand and use the consequences of "operator }". This created
an empirical rule, according to which (if you forbid yourself to "delete"
pointers explicitly and respect the RAII principles) all variables are alive
and valid until the end of the scope they were declared in. It would make
code harder to read for me (and, I suppose, a bunch of other people).
That being said, a similar situation arises with features that are
actually part of the current C++ standard. I am thinking in particular about
those people who refuse to use multiple return statements in a function. The
argument is that it breaks the empirical rule they imposed to themselves
that a function has only one end point. It breaks the flow of the program,
hence they find it less readable (I am not one of those). Same thing with
people that refuse to use goto, for similar reasons (I am one of those).
It's a matter of taste really, because 1) the standard is written so that
using these features has no undesirable side effects, and 2) in fact you can
write optimal code without multiple return statements, and you can write
optimal without goto. Much like you can write optimal code without your
{
auto reply = []() {
auto conn = []() {
auto blob = []() {
auto file = file_open_rlock("data_snippet");
return file.fetch_all();
}();
auto c = connect_to_peer("192.128.0.1");
c.send(blob);
return c;
}();
return conn.fetch_reply();
}();
auto file = file_create("output");
file.write(reply);
}
So what you are proposing is a cosmetic change (except for the special
case of function arguments, which was pointed out by Roman Perepelitsa, but
I doubt it is really useful).
I would say the points to analyze are therefore making sure that: 1) you
introduce no nasty side effects, 2) it will not make it easier for
unexperienced programmers to make mistakes, and 3) the new syntax is clearer
enough that it counter balances the increase in language complexity
(remember that this feature will have to be taught to people at some points,
think about Scott Meyer).
Although it seems at first sight that the proposal passes point 1) above,
it seems to me that this feature would only be used in very peculiar
situations, and I don't think it would be wise to use it as a general
programming habit. The problem is that it might get abused of by students,
or people coming from the C world who still have to learn that "operator }"
can do most of the job for them. My impression is therefore that it fails
point 2) and 3).
--
---
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
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
Who’s got the sweetest disposition?
One guess, that’s who?
Who’d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
c***@ncomputers.org
2014-10-24 06:01:11 UTC
Permalink
Daniel,

Thank you very much for your answer.

It is very interesting what you are suggesting.

I searched *optional.hpp* and found this code:

http://www.boost.org/doc/libs/1_56_0/boost/optional/optional.hpp

Is this which you are using?

Regards,

PF, ncomputers.org
Post by c***@cea.fr
Post by c***@ncomputers.org
Post by c***@cea.fr
So what you are proposing is a cosmetic change (except for the special
case of function arguments, which was pointed out by Roman Perepelitsa,
but
Post by c***@ncomputers.org
Post by c***@cea.fr
I doubt it is really useful).
I would say the points to analyze are therefore making sure that: 1)
you
Post by c***@ncomputers.org
Post by c***@cea.fr
introduce no nasty side effects, 2) it will not make it easier for
unexperienced programmers to make mistakes, and 3) the new syntax is
clearer
Post by c***@ncomputers.org
Post by c***@cea.fr
enough that it counter balances the increase in language complexity
(remember that this feature will have to be taught to people at some
points,
Post by c***@ncomputers.org
Post by c***@cea.fr
think about Scott Meyer).
I don't think that it is only a cosmetic change.
2) Inexperienced programmers usually don't know what stack unwinding is.
The
Post by c***@ncomputers.org
most probably is that they won't use it.
3) I think that it would be easier to explain "operator }" with an
"operator
Post by c***@ncomputers.org
unwind".
{
unsinged a;
unsigned b;
}//unwind b, unwind a;
{
unsigned a;
throw 0;//unwind a;
unsigned b;
}//if reached, unwind b;
{
unsigned a;
return 0;//unwind a;
unsigned b;
}//if reached, unwind b;
{
unsigned a;
unwind b;
unsigned a;
unwind a;
}//unwind nothing
I don't see any need of special operator since this can be achieved
http://pastebin.com/Qnba9gv8
Post by c***@ncomputers.org
PF, ncomputers
Am Donnerstag, 23. Oktober 2014 12:59:48 UTC-5 schrieb
Post by c***@cea.fr
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
Regards,
Michael
I am not so fond of the idea, especially because we have been heavily
trained to understand and use the consequences of "operator }". This
created
Post by c***@ncomputers.org
Post by c***@cea.fr
an empirical rule, according to which (if you forbid yourself to
"delete"
Post by c***@ncomputers.org
Post by c***@cea.fr
pointers explicitly and respect the RAII principles) all variables are
alive
Post by c***@ncomputers.org
Post by c***@cea.fr
and valid until the end of the scope they were declared in. It would
make
Post by c***@ncomputers.org
Post by c***@cea.fr
code harder to read for me (and, I suppose, a bunch of other people).
That being said, a similar situation arises with features that are
actually part of the current C++ standard. I am thinking in particular
about
Post by c***@ncomputers.org
Post by c***@cea.fr
those people who refuse to use multiple return statements in a
function. The
Post by c***@ncomputers.org
Post by c***@cea.fr
argument is that it breaks the empirical rule they imposed to
themselves
Post by c***@ncomputers.org
Post by c***@cea.fr
that a function has only one end point. It breaks the flow of the
program,
Post by c***@ncomputers.org
Post by c***@cea.fr
hence they find it less readable (I am not one of those). Same thing
with
Post by c***@ncomputers.org
Post by c***@cea.fr
people that refuse to use goto, for similar reasons (I am one of
those).
Post by c***@ncomputers.org
Post by c***@cea.fr
It's a matter of taste really, because 1) the standard is written so
that
Post by c***@ncomputers.org
Post by c***@cea.fr
using these features has no undesirable side effects, and 2) in fact
you can
Post by c***@ncomputers.org
Post by c***@cea.fr
write optimal code without multiple return statements, and you can
write
Post by c***@ncomputers.org
Post by c***@cea.fr
optimal without goto. Much like you can write optimal code without your
{
auto reply = []() {
auto conn = []() {
auto blob = []() {
auto file = file_open_rlock("data_snippet");
return file.fetch_all();
}();
auto c = connect_to_peer("192.128.0.1");
c.send(blob);
return c;
}();
return conn.fetch_reply();
}();
auto file = file_create("output");
file.write(reply);
}
So what you are proposing is a cosmetic change (except for the special
case of function arguments, which was pointed out by Roman Perepelitsa,
but
Post by c***@ncomputers.org
Post by c***@cea.fr
I doubt it is really useful).
I would say the points to analyze are therefore making sure that: 1)
you
Post by c***@ncomputers.org
Post by c***@cea.fr
introduce no nasty side effects, 2) it will not make it easier for
unexperienced programmers to make mistakes, and 3) the new syntax is
clearer
Post by c***@ncomputers.org
Post by c***@cea.fr
enough that it counter balances the increase in language complexity
(remember that this feature will have to be taught to people at some
points,
Post by c***@ncomputers.org
Post by c***@cea.fr
think about Scott Meyer).
Although it seems at first sight that the proposal passes point 1)
above,
Post by c***@ncomputers.org
Post by c***@cea.fr
it seems to me that this feature would only be used in very peculiar
situations, and I don't think it would be wise to use it as a general
programming habit. The problem is that it might get abused of by
students,
Post by c***@ncomputers.org
Post by c***@cea.fr
or people coming from the C world who still have to learn that
"operator }"
Post by c***@ncomputers.org
Post by c***@cea.fr
can do most of the job for them. My impression is therefore that it
fails
Post by c***@ncomputers.org
Post by c***@cea.fr
point 2) and 3).
--
---
You received this message because you are subscribed to the Google
Groups
Post by c***@ncomputers.org
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send
an
Post by c***@ncomputers.org
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
Who’s got the sweetest disposition?
One guess, that’s who?
Who’d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Jim Porter
2014-10-24 06:08:53 UTC
Permalink
Post by c***@ncomputers.org
http://www.boost.org/doc/libs/1_56_0/boost/optional/optional.hpp
Is this which you are using?
You might want to consult the paper proposing that optional be
standardized:
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4082.pdf>.
libc++ also has an implementation of n4082's optional.

- Jim
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Bjorn Reese
2014-10-24 10:15:36 UTC
Permalink
Post by c***@ncomputers.org
http://www.boost.org/doc/libs/1_56_0/boost/optional/optional.hpp
Is this which you are using?
I think Daniel was refering to the upcoming std::experiement::optional
[1], but yes it does originate from Boost.Optional.

[1] http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2013/n3793.html
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Germán Diago
2014-10-24 04:58:33 UTC
Permalink
Post by Michael Bruck
Hello everyone,
I am looking for feedback on the outline for a proposal below. I would
like to know if there is interest in such a feature and any ideas on
improvements.
I don't claim to understand your proposal completely, but one thing I think
of, if you want more control over deletions on blocks, is to just use
in-place construction with aligned memory or whatever in a buffer, and
destroy by hand.

Adding a language feature is more complexity to learn, IMHO. But I am not
sure I am covering all use cases with that.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
r***@gmail.com
2014-11-01 13:23:27 UTC
Permalink
Consider 'finalize' and 'dispose' as a candidate words too, as they are
shorter and has some precedent in other languages (Java and C#). I like
your ambition of having a consistent way to finalize a resource without
needing to remember the specific method names for each different type
(Close a handle but Free that thing and Destroy that other thing), and
introducing artificial scope via braces is just awkward sometimes. The
common case where I encounter this is when needing to briefly lock a
section of code for reading a variable, which makes braces weird because
you actually want to *keep* the scope of the object being read under lock.

What I want to do:
...
LockHolder lockHolder(object.GetLock());
String s = object.GetString();
finalize lockHolder;
...

What I end up doing:
...
String s;
{
LockHolder lockHolder(object.GetLock());
s = object.GetString();
}
...

The assignment is trivial in this case for a std::string, but declaring a
variable first with the default constructor only to replace it later is
silly.
--
---
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Loading...