220 12372 <778b6fbf-3b58-488c-9e51-32a05b95831e@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Matthew Fioravante <fmatthew5876@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Local variables that overstay their welcome
Date: Wed, 20 Aug 2014 07:24:46 -0700 (PDT)
Lines: 204
Approved: news@gmane.org
Message-ID: <778b6fbf-3b58-488c-9e51-32a05b95831e@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_262_91671357.1408544686960"
X-Trace: ger.gmane.org 1408545189 3701 80.91.229.3 (20 Aug 2014 14:33:09 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 20 Aug 2014 14:33:09 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDELF54RTIGRBL672KPQKGQEIGWG3RQ@isocpp.org Wed Aug 20 16:33:03 2014
Return-path: <std-proposals+bncBDELF54RTIGRBL672KPQKGQEIGWG3RQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pa0-f71.google.com ([209.85.220.71])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDELF54RTIGRBL672KPQKGQEIGWG3RQ@isocpp.org>)
	id 1XK6wR-0000It-1X
	for gclcip-std-proposals@m.gmane.org; Wed, 20 Aug 2014 16:32:47 +0200
Original-Received: by mail-pa0-f71.google.com with SMTP id et14sf66759258pad.2
        for <gclcip-std-proposals@m.gmane.org>; Wed, 20 Aug 2014 07:32:39 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe:content-type;
        bh=rQay0AcuQKpAJRodOxIjEneBQTAet+A88gqMzwIqFbo=;
        b=Offsa9+f21dhmbR5o9MBrcjyyNbFPSYk93xn8GE6N+WyVN0tBxCuEJvW0+BLBupCQE
         99e7mxajnpqjPVQ+S5Aiz9rBZ/7knOJ38yRXwhgxZJZHLye7i02eOduPcJnA1Xs/uEEV
         IAECkATGiBOiIhh176EM/WU8HbXHcVKWrC3+O2EGH6+0tBnUJCDQNouVdjRVMgUFYry8
         UrrF9WUVGUDPJ7nz/4v0ca6x0GdMTO6qHN3E1LyQ7dsmvHCPR9mc9zB+rPnVAon4t9Wu
         bCW4ohu0ceDJxdQSXwg4d1VAV/MuWX+6wDdqAvgE4uDJndoUEMNDKxcSK0WReah3rkqW
         eyLA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe
         :content-type;
        bh=rQay0AcuQKpAJRodOxIjEneBQTAet+A88gqMzwIqFbo=;
        b=hpMwgztvKFK4SaxtWtiR+kfd6qJTtVjl+B2KYPALQhPvN4wlLjQZb4dexeYPgD5Ghv
         36sn4dzBvbRlOTWuqnavk8iAbpM5Rpbf4Kgxn6n9TotarBlOaYKZ6EhJs0H1BFuClmY4
         15Gr0+VM7fAp7cBKWtYWJnichJMK0rBBdH7R3ZcD0sbigynFN5EsWYmxPHZl87vE69gk
         kUxV92sBwNU/tIK3nA93cWLBPVomrG40XuHQWJ5YDlYcxQ20TDlvI6prLUm7J5UZ91Nd
         B7+Egp06d6U/bhyzBt4d7qbQTWs1gzZxk9JpatXbkf++b4kPWay/fdE6YWCpFX1fvHTz
         WZfg==
X-Gm-Message-State: ALoCoQnTA9N8pWFdjS4jqJustbC58pd2UvqGyXYTn5Rl7EebYIl5fwIj056XyVw1in+YHbJP9L18
X-Received: by 10.66.163.41 with SMTP id yf9mr25566011pab.36.1408544688013;
        Wed, 20 Aug 2014 07:24:48 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.140.16.112 with SMTP id 103ls303781qga.9.gmail; Wed, 20 Aug
 2014 07:24:47 -0700 (PDT)
X-Received: by 10.140.98.243 with SMTP id o106mr13304qge.17.1408544687268;
        Wed, 20 Aug 2014 07:24:47 -0700 (PDT)
X-Original-Sender: fmatthew5876@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:12372
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/12372>

------=_Part_262_91671357.1408544686960
Content-Type: text/plain; charset=UTF-8

I've been using unique_ptr in several projects and one source of bugs I see 
in general with move only types is accidentally using the object after it 
has been moved from.
 
Lets look at some legacy code
 
struct F {
  std::vector<int*> v;
  ~F() { for(auto i: v) { delete i; } }
  void run() {
    int* i = new int();
    v.push_back(i);
    doSomethingWith(i);  
  }
};
 
Now suppose we want to convert this to using unique_ptr, a worthy goal. 
Heres a very easy mistake to make.
 
struct F {
  std::vector<std::unique_ptr<i>> v;
  void run() {
    auto i = std::make_unique<int>();
    v.push_back(std::move(i));
    doSomethingWith(i.get());
  }
};
 
The bug might be obvious in this small code snippet but if run() is a large 
function its an easy mistake to make that cannot be caught at compile time.
 
One way to mitigate this is to introduce an extra scope
 
{
  auto i = std::make_unique<int>();
  v.push_back(std::move(i));
}
doSomethingWith(i.get()); //<-compiler error, there is no variable named i!
 
But adding extra scopes is not always possible when you have many local 
variables all being used together and having different lifetimes. Also it 
adds extra indentation.
 
Do you agree that this is a big enough source of bugs that it could use a 
new feature to help the compiler detect and report these kinds of errors at 
compile time? If so, what would such a feature look like?
 
Here are some ideas:
 
1) Add a new keyword to prematurely remove an object from the current 
scope. 
 
int i = 0;
foo(i); //Ok
kill i; //<-i is removed from the scope
bar(i); //Compiler error, i does not exist anymore!
 
int j = 0;
if(something) {
  a(j); //<-Ok
  kill j; //<-j is removed from the if scope
  b(j); //<-compiler error
} 
 
c(j); //<- Ok
kill j; //<-j is removed from the scope
d(j); //compiler error
 
This could be useful because I've found many time that I wish I could 
remove a variable from the current scope when I know I won't need to use it 
anymore and I want to prevent myself from writing a typo and reusing the 
wrong variable. I sometimes find myself introducing new scopes just to 
mitigate this problem.
 
There are some complications and/or potential use cases when names clash.
 
int i;
 
void foo() {
  int i = 4;
  foo(i); //calls foo on the local i
  kill i;
  bar(i); //calls bar on the global i
}
 
With this feature, you could kill the unique_ptr after moving from it, 
preventing anyone from accidentally using it.
 
auto i = std::make_unique<int>(i);
v.push_back(std::move(i));
kill i;
doSomething(i.get()); //<-compiler error, i does not exist!
 
2) Add some kind of attribute or tag. This is almost the same thing, except 
the local variable name not actually removed from the scope. In particular 
the example with the global would not work.
 
auto i = std::make_unique<int>(i);
v.push_back(std::move(i));
std::verboten(i);
doSomething(i.get()); //<-compiler error (or warning), i is verboten
 
void foo() {
int i = 4;
foo(i); //calls foo on the local i
std::verboten(i);
bar(i); //compiler error (or warning), i is verboten!
}
 

-- 

--- 
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_262_91671357.1408544686960
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I've been using unique_ptr&nbsp;in several projects&n=
bsp;and one&nbsp;source of bugs&nbsp;I see in general with move only types =
is accidentally using the object after it has been moved from.</div><div>&n=
bsp;</div><div>Lets look at some legacy code</div><div>&nbsp;</div><div>str=
uct&nbsp;F {</div><div>&nbsp; std::vector&lt;int*&gt; v;</div><div>&nbsp; ~=
F() { for(auto i: v) { delete i; } }</div><div>&nbsp; void run() {</div><di=
v>&nbsp;&nbsp;&nbsp; int* i =3D new int();</div><div>&nbsp;&nbsp;&nbsp; v.p=
ush_back(i);</div><div>&nbsp;&nbsp; &nbsp;doSomethingWith(i);&nbsp; </div><=
div>&nbsp; }<br>};</div><div>&nbsp;</div><div>Now suppose we want to conver=
t this to using unique_ptr, a worthy goal. Heres a very easy mistake to mak=
e.</div><div>&nbsp;</div><div>struct F {</div><div>&nbsp; std::vector&lt;st=
d::unique_ptr&lt;i&gt;&gt; v;</div><div>&nbsp; void run() {</div><div>&nbsp=
;&nbsp;&nbsp; auto i =3D std::make_unique&lt;int&gt;();</div><div>&nbsp;&nb=
sp;&nbsp; v.push_back(std::move(i));</div><div>&nbsp;&nbsp;&nbsp; doSomethi=
ngWith(i.get());</div><div>&nbsp; }</div><div>};</div><div>&nbsp;</div><div=
>The bug might be obvious in this small code snippet but if run() is a larg=
e function its an easy mistake to make that cannot be caught at compile tim=
e.</div><div>&nbsp;</div><div>One way to mitigate this is to introduce an e=
xtra scope</div><div>&nbsp;</div><div>{</div><div>&nbsp; auto i =3D std::ma=
ke_unique&lt;int&gt;();</div><div>&nbsp; v.push_back(std::move(i));</div><d=
iv>}</div><div>doSomethingWith(i.get()); //&lt;-compiler error, there is no=
 variable named i!</div><div>&nbsp;</div><div>But adding extra scopes is no=
t always possible when you have many local variables all being used togethe=
r and having different lifetimes. Also it adds extra indentation.</div><div=
>&nbsp;</div><div>Do you agree that this is a big enough source of bugs tha=
t it could use a new feature to help the compiler detect and report these k=
inds of errors at compile time? If so, what would such a feature look like?=
</div><div>&nbsp;</div><div>Here are some ideas:</div><div>&nbsp;</div><div=
>1) Add a new keyword to prematurely remove an object from the current scop=
e. </div><div>&nbsp;</div><div>int i =3D 0;</div><div>foo(i); //Ok</div><di=
v>kill i; //&lt;-i is removed from the scope</div><div>bar(i); //Compiler e=
rror, i does not exist anymore!</div><div>&nbsp;</div><div>int j =3D 0;</di=
v><div>if(something) {<br>&nbsp; a(j); //&lt;-Ok</div><div>&nbsp; kill j; /=
/&lt;-j is removed from the if scope</div><div>&nbsp; b(j); //&lt;-compiler=
 error</div><div>} </div><div>&nbsp;</div><div>c(j); //&lt;- Ok</div><div>k=
ill j; //&lt;-j is removed from the scope</div><div>d(j); //compiler error<=
/div><div>&nbsp;</div><div>This could be useful because I've found many tim=
e that I wish I could remove a variable from the current scope when I know =
I won't need to use it anymore and I want to prevent myself from writing a =
typo and reusing the wrong variable. I sometimes find myself introducing ne=
w scopes just to mitigate this problem.</div><div>&nbsp;</div><div>There ar=
e some complications and/or potential use cases when names clash.</div><div=
>&nbsp;</div><div>int i;</div><div>&nbsp;</div><div>void foo() {<br>&nbsp; =
int i =3D 4;</div><div>&nbsp; foo(i); //calls foo on the local i</div><div>=
&nbsp; kill i;</div><div>&nbsp; bar(i); //calls bar on the global i</div><d=
iv>}</div><div>&nbsp;</div><div>With this feature, you could kill the uniqu=
e_ptr after moving from it, preventing anyone from accidentally using it.</=
div><div>&nbsp;</div><div><div>auto i =3D std::make_unique&lt;int&gt;(i);</=
div><div>v.push_back(std::move(i));</div><div>kill i;</div><div>doSomething=
(i.get()); //&lt;-compiler error, i does not exist!</div></div><div>&nbsp;<=
/div><div>2) Add some kind of attribute or tag. This is almost the same thi=
ng, except the local variable&nbsp;name not actually removed from the scope=
.. In particular the example with the global would not work.</div><div>&nbsp=
;</div><div>auto i =3D std::make_unique&lt;int&gt;(i);</div><div>v.push_bac=
k(std::move(i));</div><div>std::verboten(i);</div><div>doSomething(i.get())=
; //&lt;-compiler error (or warning), i is verboten</div><div>&nbsp;</div><=
div><div> </div><div>void foo() {<br>  int i =3D 4;</div><div>  foo(i); //c=
alls foo on the local i</div><div>std::verboten(i);</div><div>  bar(i); //c=
ompiler error (or warning), i is verboten!</div><div>}</div></div><div>&nbs=
p;</div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_262_91671357.1408544686960--

.
