<div dir="ltr">This is example demonstrates that we are in-general fighting hard against C++... up-hill both ways in a blizzard.  :)  This is why starting with zero features and working our way up with a white list gives examples of correct usage.  It looks like a lot of GDAL development happens by copy-paste-tweak, so good examples are key.  And for every issue, we have solutions that are valid C/C++03/C++11/C++14... the best solution is not necessarily in any particular one.<div><br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><br>
If we move to a later C++ standard, or even use features of C++98 we currently<br>
don't use, I'd advocate for using things that are obviously making the code<br>
better / more readable. Honestly who finds that<br>
"std::unique_ptr<int *, std::function<void(char *)>> Vals(CPLCalloc(256, 0),<br>
CPLFree);" is obviously more readable, efficient and less error prone than<br>
"std::vector Vals(256,0)" ?<br><br></blockquote><div><br></div><div>This is cart before the horse but... as fast as I can so expect typos.  Now just think of a ~1K long function or method with tons of instances and lots of places to bailout successfully or as failures.  We have > 9K free/CPLFree/CPLdelete/CPLDestroys that could be < ~100.</div><div><br></div><div>GDALMyBigObj *poInstance = CPLCalloc(sizeof(GDALMyBigObj);</div><div>...</div><div><div>if (oops) {</div><div>   CPLDelete(poInstance)</div><div>   return;</div><div>}<br></div></div><div>...</div><div>return;  // kaboom</div><div><div>...</div><div>if (oops) {</div><div>   CPLDelete(poInstance)</div><div>   return;</div><div>}</div></div><div>...</div><div><div>if (oops) {</div><div>   CPLDelete(poInstance)</div><div>   return;</div><div>}</div></div><div><br></div><div>CPLDelete(poInstance)</div><div>return;</div><div><br></div><div>or worse</div><div><br></div><div><div>GDALMyBigObj *poInstance = CPLCalloc(sizeof(GDALMyBigObj);</div><div>...</div><div><div><div>if (oops) {</div><div>   goto END;<br></div><div>}<br></div></div><div>...</div></div><div>// Careful what you do here because you are crossing gotos.</div><div>...</div><div><div><div>if (oops) {</div><div>   goto END;<br></div><div>}<br></div></div><div>...</div></div><div><div><div>if (oops) {</div><div>   goto END;<br></div><div>}<br></div></div><div>...</div></div><div><div>END:</div></div><div>CPLDelete(poInstance)</div><div>return;</div></div><div><br></div><div>when you could have...  And yes, getting to this is not trivial.  There are multiple things here to discuss:</div><div><br></div><div>auto poInstance = <span style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em;background-color:rgb(249,249,249)">std</span><span class="" style="font-size:12.8px;line-height:1.2em;color:rgb(0,128,128)">::</span><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em">make_unique<GDALMyBigObj>(arg1, arg2, arg3);</span></div><div><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em"><br></span></div><div><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em">if(oops)</span></div><div><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em">  return;  // Everything cleaned up nice</span></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px">...</span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px"><br></span></font></div><div><div><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em">if(oops)</span></div><div><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em">  return;  // Everything cleaned up nice</span></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px">...</span></font></div></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px"><br></span></font></div><div><div><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em">if(oops)</span></div><div><span class="" style="color:rgb(0,0,0);font-size:12.8px;line-height:1.2em">  return;  // Everything cleaned up nice</span></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px">...</span></font></div></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px"><br></span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px">return;  // Woohoo!  Success!</span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px"><br></span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px">My example of the deleter comes from real code where I don't what a heap checker barfing at me when ever a test fails.  Makes writing and debugging tests insane....</span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px"><br></span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px">// Apache 2.0 license...</span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px"><br></span></font></div><div><font color="#000000"><span style="font-size:12.8px;line-height:15.36px"><div style="">{</div><div style="">  // ...</div><div style="">  unique_ptr<OGRFeature> feature(layer->GetNextFeature());</div><div style="">  OGRGeometry *geometry = feature->GetGeometryRef();</div><div style="">  ASSERT_NE(nullptr, geometry);</div><div style=""><br></div><div style="">  char *wkt_tmp = nullptr;</div><div style="">  ASSERT_EQ(OGRERR_NONE, geometry->exportToWkt(&wkt_tmp));</div><div style="">  std::unique_ptr<char, CplFreeDeleter> wkt(wkt_tmp);</div><div style=""><br></div><div style="">  wkt_tmp = nullptr;</div><div style="">  ASSERT_STREQ("POINT (-109.27 10.3)", wkt.get());</div><div style=""><br></div><div style="">}</div></span></font></div></div><div class="gmail_signature"></div>
</div></div></div>