<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-14389137</id><updated>2024-09-13T19:00:02.027+05:30</updated><category term="C++"/><category term="vector"/><category term="boost"/><category term="memory leak"/><category term="memory management"/><category term="new"/><category term="templates"/><category term="C"/><category term="auto_ptr"/><category term="const"/><category term="delete"/><category term="smart pointers"/><category term="string"/><category term="algorithm"/><category term="custom deleters"/><category term="differences"/><category term="fstream"/><category term="function objects"/><category term="function pointers"/><category term="literals"/><category term="ostream_iterator"/><category term="post-increment"/><category term="pre-increment"/><category term="undefined behaviour"/><category term="#ifndef"/><category term="BOOST_FOREACH"/><category term="IEEE 754"/><category term="INF"/><category term="Initialization lists"/><category term="Multithreading"/><category term="NRVO"/><category term="NaN"/><category term="RVO"/><category term="TBB"/><category term="abs"/><category term="arithematic operators"/><category term="assignable"/><category term="back_inserter"/><category term="backward compatibility"/><category term="base class"/><category term="basics"/><category term="bind"/><category term="bind2nd"/><category term="binding to reference to non-const"/><category term="boost::any"/><category term="case insensitive comparison"/><category term="class"/><category term="conforming and non-conforming extensions"/><category term="const objects"/><category term="constants"/><category term="constructors"/><category term="copy"/><category term="copy constructors"/><category term="copyable"/><category term="coupling"/><category term="default members"/><category term="deque"/><category term="derived class"/><category term="duplicate"/><category term="enum"/><category term="epsilon"/><category term="equality"/><category term="erase"/><category term="exact match"/><category term="explicit constructors"/><category term="export"/><category term="extend"/><category term="extern"/><category term="find_if"/><category term="floating point comparisons"/><category term="floating point exceptions"/><category term="floating point representations"/><category term="foreach"/><category term="free"/><category term="friends"/><category term="functors"/><category term="functors with state"/><category term="gcc"/><category term="heterogenous containers"/><category term="ifstream"/><category term="implicit members"/><category term="include guards"/><category term="inheritance"/><category term="inline"/><category term="iterators"/><category term="lexical_cast"/><category term="linkage"/><category term="linker"/><category term="locale"/><category term="malloc"/><category term="memcmp"/><category term="memset"/><category term="multiple definition"/><category term="mutable"/><category term="next_permutation"/><category term="non-standard extensions"/><category term="numeric limits"/><category term="numeric_limits"/><category term="op in terms of op="/><category term="operator overloading"/><category term="operator=="/><category term="operators"/><category term="overload resolution"/><category term="padding"/><category term="permutations"/><category term="pointers"/><category term="pragma once"/><category term="ptr_fun"/><category term="rdbuf"/><category term="reference members"/><category term="references"/><category term="remove_if"/><category term="rvalue"/><category term="scope resolution operator"/><category term="serialization"/><category term="set"/><category term="shared_ptr"/><category term="sizeof"/><category term="stable_partition"/><category term="standard conversions"/><category term="static members"/><category term="std::copy"/><category term="stream operators"/><category term="stringstream"/><category term="structs"/><category term="template specialization"/><category term="temporary objects"/><category term="tokenizer"/><category term="tolerance"/><category term="tolower"/><category term="toupper"/><category term="tr1"/><category term="transform"/><category term="type-safe"/><category term="unique"/><category term="unsized arrays"/><category term="zero sized array"/><title type='text'>Learning C++</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>48</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-14389137.post-6267902752069632323</id><published>2010-04-02T17:08:00.008+05:30</published><updated>2010-04-02T18:02:58.994+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="abs"/><category scheme="http://www.blogger.com/atom/ns#" term="epsilon"/><category scheme="http://www.blogger.com/atom/ns#" term="equality"/><category scheme="http://www.blogger.com/atom/ns#" term="floating point comparisons"/><category scheme="http://www.blogger.com/atom/ns#" term="numeric limits"/><category scheme="http://www.blogger.com/atom/ns#" term="operator=="/><category scheme="http://www.blogger.com/atom/ns#" term="tolerance"/><title type='text'>Comparing floating point numbers</title><content type='html'>Floating point comparisons can be a painful work to achieve. And always must one avoid laziness in doing equality comparisons using inbuilt operator== for floating point numbers.&lt;br /&gt;&lt;br /&gt;There could be roundings involved and/or infinite decimal expansions that can lead to inaccurate representations or better say, losing of some precision off the number. Owing to that, even though you would expect a number to match a definite expansion that the calculation may have lead to, it may not.&lt;br /&gt;&lt;br /&gt;An easy way to handle that is to choose a reasonable tolerance in the comparison. For example, we could choose a tolerance of 0.0000001 when comparing two doubles for equality such that the absolute value of their difference if less than this value then, you could consider them to be equal or better say, &#39;close enough&#39; for most reasonable cases. This tolerance can, however, be insufficient if:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1) The numbers are very large or if the numbers are very small in value for the tolerance to be able to compare to their difference.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2) If there have been multiple arithematic operations performed that could lead to compounded incorrectness (owing to multiple roundings/loss of precision involved) in the result.&lt;br /&gt;&lt;br /&gt;In C++, there is a value std::numeric_limits&lt;double&gt;::epsilon() that is referred to sometimes as machine epsilon value/tolerance or machine accuracy. It gives the difference between 1 and the smallest value greater than 1 that is representable for data type for which the template&#39;s instantiated, which is double here. This helps us with the standardization of the tolerance value that we previously had chosen as 0.0000001. But doesn&#39;t help us with the limitations 1) and 2) pointed out above.&lt;br /&gt;&lt;br /&gt;There could more factors than that mentioned in 2) that can cause the rounding error. Apart from arithematic operations, it could be type promotions or binary conversions that can cause more than epsilon() rounding error. So, combination of 2 arithematic operations could lead to more than 2*epsilon. I don&#39;t know how quantifiable that is, but by a safer choice of N (number of arithematic operations involved), we hope to be able to overcome the problem in most practical cases. :-)&lt;br /&gt;&lt;br /&gt;For the short-coming mentioned in 1), we would need to bring the epsilon to the degree of large-ness or small-ness of the numbers involved. Considering this, you might have something like:&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;bool fequal(T x, T y, int N)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T diff = std::abs(x-y);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T tolerance = N*std::numeric_limits&lt;T&gt;::epsilon(); //caters to 2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return (diff &amp;lt;= tolerance*std::abs(x) &amp;&amp; diff &amp;lt;= tolerance*std::abs(y)); //caters to 1)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;where x and y are the input numbers being compared for near equality and N is the approximate number of rounding errors you are expecting.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;1) &lt;a href=&quot;http://www.petebecker.com/js/js200012.html&quot;&gt;Trap Handlers, Sticky Bits, and Floating-point Comparisons&lt;/a&gt;&lt;br /&gt;2) &lt;a href=&quot;http://www.boost.org/doc/libs/1_36_0/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html&quot;&gt;Floating-point comparison algorithms&lt;/a&gt;&lt;br /&gt;3) &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/6x7575x3(VS.80).aspx&quot;&gt;numeric_limits::epsilon&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/6267902752069632323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/6267902752069632323?isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/6267902752069632323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/6267902752069632323'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2010/04/comparing-floating-point-numbers.html' title='Comparing floating point numbers'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-570520547279076532</id><published>2010-04-02T14:11:00.008+05:30</published><updated>2010-04-02T15:26:17.151+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="floating point exceptions"/><category scheme="http://www.blogger.com/atom/ns#" term="floating point representations"/><category scheme="http://www.blogger.com/atom/ns#" term="IEEE 754"/><category scheme="http://www.blogger.com/atom/ns#" term="INF"/><category scheme="http://www.blogger.com/atom/ns#" term="NaN"/><category scheme="http://www.blogger.com/atom/ns#" term="numeric_limits"/><title type='text'>Floating point numbers and NaN</title><content type='html'>NaN expands to &#39;not a number&#39;. Various floating point operations can lead to this value. IEEE-754 is the most widely used floating point computation standards. It defines 5 possible exceptions that can occur during floating point arithematic:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1) Invalid Operation: when an invalid operation is performed on a number, for example, taking square root of a negative value, taking log of 0 or a negative number, etc.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2) Division by Zero: when a number is divided by zero&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3) Overflow: when the result is too large to be representable&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4) Underflow: when the result is too small to be representable&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5) Inexact: when the result is inexact meaning the number was rounded and caused discarding of any non-zero digits&lt;br /&gt;&lt;br /&gt;The cases falling under invalid operation would result in a value of NaN as per the above mentioned standard. (I get -INF with gcc 3.4.4, but NaN for any negative number&#39;s logarithm). You would check for NaNs and Infinities resulting out of computations in order to determine the success and validity of the operation but that can lead to code that is cluttered with ifs and elses and can become almost un-readable. You can, however, do the checks at every logical chunk of the computation. However, NaNs and INFs can get lost mid-calculations. The standard dictates that an exceptional value NaN or INF should get propagated throughout the calculations so that the checks at the end of a computation could catch them but certain operations can lose them, for example:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1) NaN operation with INF value would result in INF, as in NaN + INF = INF.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2) INF can become 0, as in x/INF = 0&lt;br /&gt;&lt;br /&gt;The way to catch these would be to check the sticky bits that are essentially the exception flags that are set on occurence of floating point exceptions anywhere during the calculation. But let&#39;s not get too carried away and leave it to the credibility of the programmers and users to be able to handle the various cases in the most sensible way. :-)&lt;br /&gt;&lt;br /&gt;To conclude, here is a function that will help check if a value is a NaN or not, based on the fact that any comparison involving NaNs would result in &#39;false&#39; result:&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;bool myIsNaN(T value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return value != value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;C99 has a function isNaN() and TR1 for C++ has included the support for this function but just in case your compiler doesn&#39;t support it. Similarly, you have isinf() that will help catch both positive and negative infinities. If you are feeling too experimental, try your own version of isinf() using numeric limits. :-)&lt;br /&gt;&lt;br /&gt;References: &lt;br /&gt;&lt;br /&gt;1) &lt;a href=&quot;http://www.petebecker.com/js/js200012.html&quot;&gt;Trap Handlers, Sticky Bits, and Floating-point Comparisons&lt;/a&gt;&lt;br /&gt;2) &lt;a href=&quot;http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.15&quot;&gt;What is this NaN thing?&lt;/a&gt;&lt;br /&gt;3) &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/34stz20a(v=VS.80).aspx&quot;&gt;C++ Numeric limits&lt;/a&gt;&lt;br /&gt;4) &lt;a href=&quot;http://en.wikipedia.org/wiki/IEEE754&quot;&gt;Wikipedia - IEEE 754&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/570520547279076532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/570520547279076532?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/570520547279076532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/570520547279076532'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2010/04/floating-point-numbers-and-nan.html' title='Floating point numbers and NaN'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-6165719376059803857</id><published>2010-03-27T15:33:00.001+05:30</published><updated>2010-03-27T15:34:35.672+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="enum"/><category scheme="http://www.blogger.com/atom/ns#" term="extend"/><category scheme="http://www.blogger.com/atom/ns#" term="inheritance"/><title type='text'>Extending enums</title><content type='html'>There might come a scenario where you want to include an enum into a another one where the first one is a subset.&lt;br /&gt;&lt;br /&gt;#include &lt;cstdio&gt; &lt;br /&gt;struct enum_a { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  enum constant { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    a, b, c, d, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    end_of_enum_a = d &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  }; &lt;br /&gt;}; &lt;br /&gt;struct enum_b : public enum_a { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  enum constant { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    e = end_of_enum_a + 1, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    f, g, h &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  }; &lt;br /&gt;}; &lt;br /&gt;int main() { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  std::printf(&quot;enum_a: a(%d), b(%d), c(%d), d(%d)\n&quot;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    enum_b::a, enum_b::b, enum_b::c, enum_b::d); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  std::printf(&quot;enum_b: e(%d), f(%d), g(%d), h(%d)\n&quot;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    enum_b::e, enum_b::f, enum_b::g, enum_b::h); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  return 0; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;Inheritance to the rescue. :-)</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/6165719376059803857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/6165719376059803857?isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/6165719376059803857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/6165719376059803857'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2010/03/extending-enums.html' title='Extending enums'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-768730989542502220</id><published>2009-07-28T21:29:00.006+05:30</published><updated>2009-07-28T21:55:46.328+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="backward compatibility"/><category scheme="http://www.blogger.com/atom/ns#" term="C"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="const"/><category scheme="http://www.blogger.com/atom/ns#" term="function pointers"/><category scheme="http://www.blogger.com/atom/ns#" term="literals"/><category scheme="http://www.blogger.com/atom/ns#" term="rvalue"/><category scheme="http://www.blogger.com/atom/ns#" term="standard conversions"/><category scheme="http://www.blogger.com/atom/ns#" term="string"/><category scheme="http://www.blogger.com/atom/ns#" term="undefined behaviour"/><title type='text'>String literals in C++</title><content type='html'>Here&#39;s a short one on string literals in C++. Ask yourself: what is their type? It is &#39;array of n const char&#39;, correct! So, we might think:&lt;br /&gt;&lt;br /&gt;    char* literal = &quot;Hello World!&quot;;&lt;br /&gt;&lt;br /&gt;would be &quot;invalid&quot;/&quot;illegal&quot; in C++. But you&#39;d be surprised it is not and even Comeau online compiles it successfully without even a warning. &lt;br /&gt;&lt;br /&gt;The C++ standard, however, tries to protect you hinting that the above is wrong by stating that it is a deprecated feature in C++ that probably was allowed to keep backward compatibility with C.&lt;br /&gt;&lt;br /&gt;Here is what the standard says as part of section [2.13.4/2]:&lt;br /&gt;&lt;br /&gt;[quote]&lt;br /&gt;A string literal that does not begin with u, U, or L is an ordinary string literal, also referred to as a narrow string literal. An ordinary string literal has type “array of n const char”, where n is the size of the string as defined below; it has static storage duration (3.7) and is initialized with the given characters.&lt;br /&gt;[/quote]&lt;br /&gt;&lt;br /&gt;So, the following would have definitely been invalid in C++:&lt;br /&gt;&lt;br /&gt;    char* literal = &quot;Hello World!&quot;;&lt;br /&gt;&lt;br /&gt;&quot;Hello World!&quot; is an array of 13 [spooky :-)] constant characters. &#39;literal&#39; is the pointer to the first element of the array and since that element is const, the pointer cannot be declared as a non-const char*. The pointer has to be of the type &#39;pointer to a const char&#39;.&lt;br /&gt;&lt;br /&gt;But as mentioned above, to have backward compatibility with C where the above works an implicit conversion is defined for array to pointer conversion where a string literal would be converted to an r-value of type &quot;pointer to a char&quot;. The standard mentions this in section [4.2/2]:&lt;br /&gt;&lt;br /&gt;[quote]&lt;br /&gt;A string literal (2.13.4) with no prefix, with a u prefix, with a U prefix, or with an L prefix can be converted to an rvalue of type “pointer to char”, “pointer to char16_t”, “pointer to char32_t”, or “pointer to wchar_t”, respectively. In any case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue. [ Note: this conversion is deprecated. See Annex D. —end note ]&lt;br /&gt;[/quote]&lt;br /&gt;&lt;br /&gt;But, the thing to be happy about is the note above, that is re-iterated in Annexure D section [D.4/1] as:&lt;br /&gt;&lt;br /&gt;[quote]&lt;br /&gt;The implicit conversion from const to non-const qualification for string literals (4.2) is deprecated.&lt;br /&gt;[/quote]&lt;br /&gt;&lt;br /&gt;So, best is to keep the good habit of declaring the pointer to the literal as a pointer to a const. :-)&lt;br /&gt;&lt;br /&gt;[The C++ standard&#39;s draft version used for quotes above, has document number : N2315=07-0175 dated 2007-06-25]</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/768730989542502220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/768730989542502220?isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/768730989542502220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/768730989542502220'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2009/07/string-literals-in-c.html' title='String literals in C++'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-3624533611427771447</id><published>2009-03-01T14:23:00.002+05:30</published><updated>2009-03-01T14:26:55.545+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="scope resolution operator"/><category scheme="http://www.blogger.com/atom/ns#" term="static members"/><title type='text'>Accessing static members of a class</title><content type='html'>Static members of a class are not associated with any one particular instance/object of it. They can even be accessed without any instance. The way to refer to them in your code is as shown below:&lt;br /&gt;&lt;br /&gt;[CODE]&lt;br /&gt;class Test&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static const std::string className;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static const std::string&amp; getClassName()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return className;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//other members&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; Test::getClassName();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;It is also allowed to be able to access the static members via an instance/object as below: (modifying the above main function and keeping reset the same)&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Test testObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; testObject.getClassName();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Usually though, it is better to use the previous notation using the scope resolution operator (op &#39;::&#39;). That makes the code more readable in the sense that you know it is a static member and not a non-static one. It speaks for itself.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/3624533611427771447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/3624533611427771447?isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3624533611427771447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3624533611427771447'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2009/03/accessing-static-members-of-class.html' title='Accessing static members of a class'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-1449582890610766636</id><published>2009-01-24T22:48:00.002+05:30</published><updated>2009-01-24T22:53:41.022+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="export"/><category scheme="http://www.blogger.com/atom/ns#" term="inline"/><category scheme="http://www.blogger.com/atom/ns#" term="linker"/><category scheme="http://www.blogger.com/atom/ns#" term="multiple definition"/><category scheme="http://www.blogger.com/atom/ns#" term="template specialization"/><title type='text'>Inline specializations and multiple inclusions</title><content type='html'>Recently, I came across a problem being faced by an individual on the forums. He had the code like this:&lt;br /&gt;&lt;br /&gt;[CODE]&lt;br /&gt;//file: header.h&lt;br /&gt;#ifndef HEADER_H&lt;br /&gt;#define HEADER_H&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;template&amp;lt;class T&amp;gt;&lt;br /&gt;void foo(T val){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; &quot;foo&amp;lt;T&amp;gt;(&quot;&amp;lt;&amp;lt;val&amp;lt;&amp;lt;&quot;)\n&quot;;&lt;br /&gt;}&lt;br /&gt;template&amp;lt;&amp;gt;&lt;br /&gt;inline void foo(double val){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; &quot;foo&amp;lt;double&amp;gt;(&quot; &amp;lt;&amp;lt; val &amp;lt;&amp;lt;&quot;)\n&quot;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;//file: main.cpp&lt;br /&gt;#include &quot;header.h&quot;&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double x=4;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo(x);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//file: other.cpp&lt;br /&gt;#include &quot;header.h&quot;&lt;br /&gt;void somecode(){}&lt;br /&gt;&lt;br /&gt;Just to summarize the above code, there is a header file (header.h) that contains the template functions and its specialization on type &#39;double&#39; for template type parameter declared inline. And that header is being included into 2 implementation files (main.cpp &amp; other.cpp)&lt;br /&gt;&lt;br /&gt;This code compiled fine for him but as soon as he removed the inline keyword, it started to given him linker error for multiple definitions of the foo&amp;lt;double&amp;gt; function. We might start wondering what is it between templates and inline that might be causing this? Something and nothing. What happens is explained below:&lt;br /&gt;&lt;br /&gt;The linker error seen is not specific to templates or specializations. One will face the same problem if they turned foo into a non-template function. C++ functions have external linkage hence they must be implemented in just one .cpp file (implementation file). They can, however, be declared multiple times. When we provide the implementation in the header file instead of an implementation file and that header is being included multiple implementation files (main.cpp and other.cpp), we have multiple definitions and hence, rightly the linkage error. Putting the implementation into the header file was what we were forced to do when using a template function because we need to put the implementation in the header file as well as the declaration since &#39;export&#39; doesn&#39;t work except for just with the Comeau compiler. But specializations are a different case than regular templates. We don&#39;t face such issues with regular templates (not their specializations) because the instantiation rules guarantees that there is just one copy of the function generated as and when needed. While in case of specializations, we end up with multiple definitions because of them being included into multiple implementation files.&lt;br /&gt;&lt;br /&gt;Now, with inline functions, we provide the implementation in the header file so as to be visible to the compilation point where they are used. They become inline in the final executable or not is irrelevant. You just follow the rule to define the inline functions. There will be only one copy of them.&lt;br /&gt;&lt;br /&gt;Coming to the solutions to the above linker error, below are the two simplest ways:&lt;br /&gt;&lt;br /&gt;1. Make the specialization as inline (as in original code, in case, someone facing this issue didn&#39;t have it in the first place)&lt;br /&gt;&lt;br /&gt;2. Declare it not as a specialization but just as an overloaded foo function and declare it in the header (header.h) and provide implementation in an implementation file (for that matter any one implementation main.cpp/other.cpp or a .cpp of its own for header.h templates&#39; specializations just making sure we don&#39;t do it twice).&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;1. Codeguru thread where I came across this - &quot;inline&quot; and linking errors&lt;br /&gt;2. C++ FAQ Lite on Inline Functions</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/1449582890610766636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/1449582890610766636?isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1449582890610766636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1449582890610766636'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2009/01/inline-specializations-and-multiple.html' title='Inline specializations and multiple inclusions'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-829258675585750122</id><published>2008-08-15T22:04:00.004+05:30</published><updated>2008-08-15T22:11:17.612+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="algorithm"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="next_permutation"/><category scheme="http://www.blogger.com/atom/ns#" term="ostream_iterator"/><category scheme="http://www.blogger.com/atom/ns#" term="permutations"/><category scheme="http://www.blogger.com/atom/ns#" term="std::copy"/><category scheme="http://www.blogger.com/atom/ns#" term="string"/><category scheme="http://www.blogger.com/atom/ns#" term="vector"/><title type='text'>Permutations in C++</title><content type='html'>A small simple sample that illustrates how to get the various permutations of the characters of a string in C++ using std::next_permutation provided under the standard include &amp;lt;algorithm&amp;gt;.&lt;br /&gt;&lt;br /&gt;[code]&lt;br /&gt;#include&amp;lt;algorithm&amp;gt;&lt;br /&gt;#include&amp;lt;string&amp;gt;&lt;br /&gt;#include&amp;lt;vector&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string input=&quot;ABC&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::vector&amp;lt;std::string&amp;gt; perms;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;perms.push_back(input);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string::iterator itBegin = input.begin();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string::iterator itEnd = input.end();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(std::next_permutation(itBegin, itEnd))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;perms.push_back(std::string(itBegin, itEnd));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::copy(perms.begin(), perms.end(), std::ostream_iterator&amp;lt;std::string&amp;gt;(std::cout, &quot;\n&quot;));&lt;br /&gt;}&lt;br /&gt;[/code]</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/829258675585750122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/829258675585750122?isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/829258675585750122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/829258675585750122'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/08/permutations-in-c.html' title='Permutations in C++'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-5847085520208889480</id><published>2008-07-27T18:31:00.004+05:30</published><updated>2008-07-27T19:10:08.734+05:30</updated><title type='text'>C++ unions : how to find currently active member</title><content type='html'>C++ unions can have member functions. And to surprise you even more, they can have constructors and a destructor. But that&#39;s not all that I intend to write about. A question straightaway comes into our mind: If unions can have member functions, how would you know which of its data member is currently &#39;active&#39; or &#39;set&#39; (well, this can come up even in case they don&#39;t have member functions, not very specific to them).&lt;br /&gt;&lt;br /&gt;This is important to know because if say member1 of the union is set then that is the one that is active and you can only access its value. Accessing value of any of the other members is undefined behavior as per the standard and we all know what undefined behavior means; it may work in your case, on your machine, and it can fail you in front of a very potential client of yours or your managers when demo-ing your application.&lt;br /&gt;&lt;br /&gt;Here is a way; you can let your member functions (is applicable to unions in general) know which data member is currently set:&lt;br /&gt;&lt;br /&gt;[code]&lt;br /&gt;union myunion&lt;br /&gt;{&lt;br /&gt;    int member; //if == 1 then mem1 is set, use it; if ==2 mem2 is set, use it&lt;br /&gt;    struct&lt;br /&gt;    {&lt;br /&gt;        int struct_id;  //1&lt;br /&gt;&lt;br /&gt;        //other members&lt;br /&gt;    } mem1;&lt;br /&gt;    struct&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        int struct_id;  //2&lt;br /&gt;        //other members&lt;br /&gt;    } mem2;&lt;br /&gt;    //and so on...&lt;br /&gt;    void memfunc()&lt;br /&gt;    {&lt;br /&gt;        //could use a switch&lt;br /&gt;        if(member==1)&lt;br /&gt;        {&lt;br /&gt;            //use mem1&lt;br /&gt;        }&lt;br /&gt;        else if (member ==2)&lt;br /&gt;        {&lt;br /&gt;            //use mem2&lt;br /&gt;        }&lt;br /&gt;        //and so on...&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;[/code]&lt;br /&gt;&lt;br /&gt;The in-lined comments are self explanatory. The member variable &#39;member&#39; can be used as a signifier as to which of the other struct members is currently active, reading which is not unsafe. What makes it safe, you might wonder? To understand the guarantee that the programmer is provided with, let&#39;s go through what the C++ standard has to say about it. Quote: 18.5 [class.union]/1 provides the rules that suffice the above explanations. I will quote that paragraph in full below:&lt;br /&gt;&lt;br /&gt;[quote]&lt;br /&gt;In a union, at most one of the data members can be active at any time, that is, the value of at most one of the data members can be stored in a union at any time. [Note: one special guarantee is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout structs that share a common initial sequence (9.2), and if an object of this standard-layout union type contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of standard-layout struct members; see 9.2. —end note] The size of a union is sufficient to contain the largest of its data members. Each data member is allocated as if it were the sole member of a struct. A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class. An object of a non-trivial class (clause 9) shall not be a member of a union, nor shall an array of such objects. If a union contains a static data member or a member of reference type the program is ill-formed.&lt;br /&gt;[/quote]&lt;br /&gt;&lt;br /&gt;The above tells you that member functions are allowed with unions including constructors and destructors. It also makes a statement that structs inside a union that follow a common initial sequence, it is legal to inspect (i.e. query or read the value of) that common initial sequence. Also, it says that, each data member is allocated as if it were the sole member of a struct. In our example above, &#39;member&#39; is such a data member. It is as if you have a struct as a member of the union with just a single data member of type &#39;int&#39;.&lt;br /&gt;&lt;br /&gt;Moreover, there is another mention in section 9.2/18 as follows:&lt;br /&gt;&lt;br /&gt;[Quote]&lt;br /&gt;A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. —end note]&lt;br /&gt;[/quote]&lt;br /&gt;&lt;br /&gt;Considering the above quotes, it is guaranteed that, each &#39;struct_id&#39; (in the code sample above) shares the same layout as the first member of the union of int type &quot;member&quot;. And hence using them (being the same initial sequence) in a union is perfectly safe, independent of which union member had been previously set (or is active).&lt;br /&gt;&lt;br /&gt;This (the int member &#39;member&#39;) allows us to have a convenient way to see which data member of the union is currently active without peeping into any specific struct members (not that it is impossible) and without causing any effect on the size of the union.&lt;br /&gt;&lt;br /&gt;Having member functions find out the active member that way is a little inextensible. What if you plan to add another struct member? You would need to enhance the switch statement, or the if-else-if conditionals to accommodate that. But then, even in case unions have no member functions, you might very well need to know that information and the above method helps.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/5847085520208889480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/5847085520208889480?isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/5847085520208889480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/5847085520208889480'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/07/c-unions-can-have-functions.html' title='C++ unions : how to find currently active member'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-3658575478885248427</id><published>2008-05-03T17:31:00.011+05:30</published><updated>2008-05-05T09:40:54.500+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C"/><category scheme="http://www.blogger.com/atom/ns#" term="memcmp"/><category scheme="http://www.blogger.com/atom/ns#" term="memset"/><category scheme="http://www.blogger.com/atom/ns#" term="padding"/><category scheme="http://www.blogger.com/atom/ns#" term="sizeof"/><category scheme="http://www.blogger.com/atom/ns#" term="structs"/><title type='text'>comparing structs with memcmp</title><content type='html'>Can you use memcmp to compare C style structs reliably? Let&#39;s first see what the C-standards has to say about the function: memcmp.&lt;br /&gt;&lt;br /&gt;From the C-standards, 7.21.4.1/The memcmp function:&lt;br /&gt;&lt;br /&gt;[QUOTE]&lt;br /&gt;Synopsis&lt;br /&gt;1 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;int memcmp(const void *s1, const void *s2, size_t n);&lt;br /&gt;&lt;br /&gt;Description&lt;br /&gt;2 The memcmp function compares the first n characters of the object pointed to by s1 to the first n characters of the object pointed to by s2.(248))&lt;br /&gt;&lt;br /&gt;Returns&lt;br /&gt;3 The memcmp function returns an integer greater than, equal to, or less than zero, accordingly as the object pointed to by s1 is greater than, equal to, or less than the object pointed to by s2.&lt;br /&gt;[QUOTE END]&lt;br /&gt;&lt;br /&gt;The footnote (248) mentioned above is important and interesting:&lt;br /&gt;&lt;br /&gt;[QUOTE]&lt;br /&gt;The contents of ‘‘holes’’ used as padding for purposes of alignment within structure objects are indeterminate. &amp;lt;snipped&amp;gt;&lt;br /&gt;[QUOTE END]&lt;br /&gt;&lt;br /&gt;There&#39;s our trouble. Indeterminate values. There can be unused padding bytes with structures as need by alignment requirements for a platform and how they are filled is not defined by the standard. It is not even mentioned if they are going to be initialized or how they get initialized. You might get lucky with the indeterminate values but in the programming world, we always consider ourselves unlucky with something like that. So, unless you are very sure that there is no padding memcmp is rendered useless. You can find if your struct has padding or not as below :&lt;br /&gt;&lt;br /&gt;[CODE]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (sizeof(mystruct) == sizeof(member1) + sizeof(member2) /*+ ..so on...*/)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//no padding - probably can use memcmp - but are you really sure!!!???&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//has definitely some padding - dont use memcmp&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;[CODE END]&lt;br /&gt;&lt;br /&gt;Even though you find no padding, it is not safe to do memcmp in all cases. One reason that I can make out is because +0 and -0 for us would be same. They should evaluate equal but memcmp would not think the same way. To generalize it, whenever there are more than one bit representation of a particular value, memcmp may report false negatives, when the values might be equal but comparing their bit pattern comes unequal.&lt;br /&gt;&lt;br /&gt;Below are few points of concern would prevent reliable use of memcmp to comparing 2 structs or even 2 basic fundamental datatypes or an array of those:&lt;br /&gt;&lt;br /&gt;1. Unused bits : Not all bits for a type (except unsigned char) are used for its value representation. For example, on a platform where an int is 4 bytes and considering that for the platform, a byte has 8 bits, not all 32 bits be used to represent the value held by an int. So, on such platforms the largest possible value of an int may not be 2^(32-1) but lesser. How the unused bits are filled is implementation specific and hence memcmp would not be reliable to even compare the basic fundamental types like int even when the values are equal. The unused bits are called holes.&lt;br /&gt;&lt;br /&gt;2. Padding bytes : Padding bytes within a struct between 2 members of the struct to cater to alignment requirements. The padded bytes will have indeterminate values that may compare equal or unequal in a non-deterministic way. So, memcmp would lead to false negatives for comparison. However, the positives returned would be reliable but that would be a smaller set out of the possible positives of the comparison.&lt;br /&gt;&lt;br /&gt;3. Unreliable treatment of unused bits and padding bytes after memset : memset on the types or structs can probably work around the uninitialized padding bytes/holes indeterminate values (as it treats the data as a sequence of unsigned chars which have no holes) but there can be other reasons to failure and who knows if the values of those padding bytes might change during the process of the program between a memset call and a memcmp call. If the standards explicitly prohibits an implementation from doing so, please let me know and I shall correct myself. The relevant quote would be fantastic!&lt;br /&gt;&lt;br /&gt;4. Floating types : floating point numbers cannot even be compared reliably using ==, forget about memcmp. They always need to be compared to be a around each other but varying by some value of epsilon() as defined by the compiler.&lt;br /&gt;&lt;br /&gt;5. Pointer representation : Pointer&#39;s bit representations can be different for the same linear address and two completely different pointers may compare equal. Of particular peculiarity is the segment:offset representation where two different segment::offset pair values stored in a pointer&#39;s representation may actually by referring to the same linear address. Linear address here = segment*16 +offset. You will get 2 different pairs of segment and offset for which the equation would evaluate to the same linear address. The inbuilt == operator is guaranteed to work such that two pointers of the same type pointing to the same object will always compare equal. This is also considering you are just wanting to compare the pointers and not the values pointed to by them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Considering the above cases when memcmp would be unreliable, I would choose member wise comparison to be the solution to choose to compare 2 structs of same type. If the structs are different types with comparable members (but could be of different types), memcmp would probably fail more miserably. If it is a non-POD struct, it is simply undefined behaviour.&lt;br /&gt;&lt;br /&gt;It is worth going through the following discussion on comp.lang.c that discuss the above in greater detail : &lt;a href=&quot;http://groups.google.co.uk/group/comp.lang.c/browse_thread/thread/3392a7be0beaafd1/c0a788fb2fe4c83a&quot;&gt;Expert-Q: (a!=b) != memcmp(&amp;a, &amp;b, sizeof a) ?&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/3658575478885248427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/3658575478885248427?isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3658575478885248427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3658575478885248427'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/05/comparing-structs-with-memcmp.html' title='comparing structs with memcmp'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-1282482086063596644</id><published>2008-04-19T23:33:00.005+05:30</published><updated>2008-04-19T23:52:52.406+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="boost"/><category scheme="http://www.blogger.com/atom/ns#" term="BOOST_FOREACH"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="foreach"/><category scheme="http://www.blogger.com/atom/ns#" term="fstream"/><category scheme="http://www.blogger.com/atom/ns#" term="ifstream"/><category scheme="http://www.blogger.com/atom/ns#" term="tokenizer"/><title type='text'>boost::tokenizer and BOOST_FOREACH</title><content type='html'>I looked at the &lt;a href=&quot;http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html&quot;&gt;documentation&lt;/a&gt; for what all could foreach macro support? The list didn&#39;t have boost tokenizer in it, which was expected but it said something that meant, it should work: &quot;The support for STL containers is very general; anything that looks like an STL container counts. If it has nested iterator and const_iterator types and begin() and end() member functions, BOOST_FOREACH will automatically know how to iterate over it.&quot;&lt;br /&gt;&lt;br /&gt;So, I tried it out and yes, it worked. The following compiled and worked fine with VC++ 2005. The code should be easy to understand that basically, reads a file line by line and tokenizes the lines assuming a space or punctuation as the seperator.&lt;br /&gt;&lt;br /&gt;[code]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//standard headers&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include &amp;lt;string&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//boost headers&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include &amp;lt;boost/tokenizer.hpp&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include &amp;lt;boost/foreach.hpp&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//make BOOST_FOREACH &lt;a href=&quot;http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html#foreach.introduction.making__literal_boost_foreach__literal__prettier&quot;&gt;prettier&lt;/a&gt;! ;-) :-)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#define foreach BOOST_FOREACH&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void tokenizeLines(std::istream&amp; inputStream)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(inputStream)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string line;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(std::getline(inputStream, line, &#39;\n&#39;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;boost::tokenizer&amp;lt;&amp;gt; tokens(line);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach(const std::string &amp; str, tokens)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; str &amp;lt;&amp;lt; &quot;\n&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cerr &amp;lt;&amp;lt; &quot;Error: Invalid stream object\n&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::ifstream inputStream(&quot;C:\\testfiles\\myfile.txt&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tokenizeLines(inputStream);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/1282482086063596644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/1282482086063596644?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1282482086063596644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1282482086063596644'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/04/boosttokenizer-and-boostforeach.html' title='boost::tokenizer and BOOST_FOREACH'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-8994129177098215375</id><published>2008-04-16T19:56:00.004+05:30</published><updated>2008-04-16T20:12:02.771+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="back_inserter"/><category scheme="http://www.blogger.com/atom/ns#" term="bind"/><category scheme="http://www.blogger.com/atom/ns#" term="bind2nd"/><category scheme="http://www.blogger.com/atom/ns#" term="boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="case insensitive comparison"/><category scheme="http://www.blogger.com/atom/ns#" term="locale"/><category scheme="http://www.blogger.com/atom/ns#" term="ptr_fun"/><category scheme="http://www.blogger.com/atom/ns#" term="string"/><category scheme="http://www.blogger.com/atom/ns#" term="tolower"/><category scheme="http://www.blogger.com/atom/ns#" term="toupper"/><category scheme="http://www.blogger.com/atom/ns#" term="tr1"/><category scheme="http://www.blogger.com/atom/ns#" term="transform"/><title type='text'>Case insensitive string comparison</title><content type='html'>While looking up for case insensitive comparison function, I came across this nice article by Matt Austern : &lt;a href=&quot;http://lafstern.org/matt/col2_new.pdf&quot;&gt;Case Insensitive String Comparison&lt;/a&gt;). And decided to try to make a sample that does that. Below is the result, am not sure if it is perfect and has no issues but that is the best I could do. Atleast, better than ignoring the locale completely! Yes, ignoring it would work most of the times as it&#39;s not needed but just in case, a need came up, what would you do?&lt;br /&gt;&lt;br /&gt;I tested the code with VS 2005 (couldn&#39;t test it with gcc as I found out that I did not have support for the german locale as I only had the sample strings for that language (out of the above article) and I felt lazy enough to find more sample to test) but if someone finds an issue with some other language words for which your compiler provides locale support, can you please point it out?&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include&amp;lt;iostream&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include&amp;lt;locale&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include&amp;lt;string&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include&amp;lt;algorithm&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include&amp;lt;functional&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//used boost::bind due to buggy bind2nd&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//#include&amp;lt;tr1/bind.hpp&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#include&amp;lt;boost/bind.hpp&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//using namespace std;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//using namespace std::tr1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//using namespace std::tr1::placeholders;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;using namespace boost;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;struct CaseInsensitiveCompare&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool operator()(const std::string&amp; lhs, const std::string&amp; rhs)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string lhs_lower;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string rhs_lower;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//std::transform(lhs.begin(), lhs.end(), std::back_inserter(lhs_lower), std::bind2nd(std::ptr_fun(std::tolower&amp;lt;char&amp;gt;), loc));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//std::transform(rhs.begin(), rhs.end(), std::back_inserter(rhs_lower), std::bind2nd(std::ptr_fun(std::tolower&amp;lt;char&amp;gt;), loc));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::transform(lhs.begin(), lhs.end(), std::back_inserter(lhs_lower), bind(std::tolower&amp;lt;char&amp;gt;, _1, loc));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::transform(rhs.begin(), rhs.end(), std::back_inserter(rhs_lower), bind(std::tolower&amp;lt;char&amp;gt;, _1, loc));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return lhs_lower &amp;lt; rhs_lower;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CaseInsensitiveCompare(const std::locale&amp; loc_): loc(loc_){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::locale loc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string lhs = &quot;GEW\334RZTRAMINER&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string rhs = &quot;gew\374rztraminer&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; &quot;lhs : &quot; &amp;lt;&amp;lt; lhs &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; &quot;rhs : &quot; &amp;lt;&amp;lt; rhs &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CaseInsensitiveCompare cis((std::locale(&quot;German_germany&quot;)));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//CaseInsensitiveCompare cis((std::locale()));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; &quot;compare result : &quot; &amp;lt;&amp;lt; cis(lhs,rhs) &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;One obvious improvement/alternative could be not copying the strings and instead doing a per character based tolower/toupper and compare them. This has a 2nd advantage as well that it will break out as soon as a mismatch happens for a character, without the need to convert the whole 2 strings into a common case.&lt;br /&gt;&lt;br /&gt;Herb Sutter, in one of his Gotw&#39;s, writes about a case insensitive string class but also shows the basic problems that would have. Quite simply put, it doesn&#39;t work with iostreams (cout/cerr etc). Here: &lt;a href=&quot;http://www.gotw.ca/gotw/029.htm&quot;&gt;Strings: A case insensitive string class&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/8994129177098215375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/8994129177098215375?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/8994129177098215375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/8994129177098215375'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/04/case-insensitive-string-comparison.html' title='Case insensitive string comparison'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-5371172182643351445</id><published>2008-04-13T11:05:00.009+05:30</published><updated>2008-05-16T21:49:22.566+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="duplicate"/><category scheme="http://www.blogger.com/atom/ns#" term="erase"/><category scheme="http://www.blogger.com/atom/ns#" term="set"/><category scheme="http://www.blogger.com/atom/ns#" term="unique"/><category scheme="http://www.blogger.com/atom/ns#" term="vector"/><title type='text'>Remove duplicates from vector</title><content type='html'>Q. How do you remove duplicates from a vector?&lt;br /&gt;&lt;br /&gt;A. This is how:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template&amp;lt;typename T&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void removeDuplicates(std::vector&amp;lt;T&amp;gt;&amp; vec)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::sort(vec.begin(), vec.end());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vec.erase(std::unique(vec.begin(), vec.end()), vec.end());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;If I needed a container to keep itself populated of only unique values, I would probably choose std::set but then choosing the right container depends on so many other different factors as well.&lt;br /&gt;&lt;br /&gt;Edit Comment : Corrected above by replacing remove with erase as there isn&#39;t such a member function in std::vector. std::erase, however, is and the code works with just that replacement.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/5371172182643351445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/5371172182643351445?isPopup=true' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/5371172182643351445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/5371172182643351445'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/04/remove-duplicates-from-vector.html' title='Remove duplicates from vector'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-3276155717123572278</id><published>2008-04-12T10:23:00.005+05:30</published><updated>2008-04-12T14:06:41.479+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="const objects"/><category scheme="http://www.blogger.com/atom/ns#" term="copy constructors"/><category scheme="http://www.blogger.com/atom/ns#" term="temporary objects"/><title type='text'>Copy constructor forms</title><content type='html'>The copy constructor can have both forms(*) as below:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A(A&amp; rhs);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A(const A&amp; rhs);&lt;br /&gt;&lt;br /&gt;Both are perfectly valid and it is pretty easy to forget the &#39;const&#39; for the rhs argument. The compiler accepts it as a perfectly valid syntax thinking that is what your intent was. But the above two are a bit different from each other. The first one rejects to work with/copy from parameters that are not const objects of type A as well as temporaries. So, if you tried something like this:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const A const_a;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A copy_const_a(const_a);  //ERROR!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A copy_from_temp(A(/*some arguments*/)); //ERROR!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A copy_from_return_val(somefunc_return_A_by_val); //ERROR!&lt;br /&gt;//any other forms that might want to create copies out of const or temorary objects&lt;br /&gt;&lt;br /&gt;the compiler will just shout at you at the appropriateness of the copy constructor you wrote. And if you by any chance overlooked the argument for your it assuming it be correct, you would most certainly lose some of your precious time thinking probably some of your member objects are not copy constructible or there&#39;s some issue of that sort.&lt;br /&gt;&lt;br /&gt;This brings us to the primary point of const correctness. Make things const, declare them const unless you explicitly wanted them to be non-const. I know some people who have the opinion that this should have been implicit by the language and to make something non-const there should have been a keyword i.e. there were a keyword &#39;mutable&#39; (not in the sense that it is used in the language currently) or something similar to let know that the object is non-const. But it&#39;s probably too late for it. :-)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(*) Or for that matter any of the 4 forms as mentioned below:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A(A&amp; rhs /*, either no other args or all default args*/); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A(const A&amp; rhs /*, either no other args or all default args*/);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A(volatile A&amp; rhs /*, either no other args or all default args*/);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A(const volatile A&amp; rhs  /*, either no other args or all default args*/);</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/3276155717123572278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/3276155717123572278?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3276155717123572278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3276155717123572278'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/04/copy-constructor-forms.html' title='Copy constructor forms'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-6806285288841477372</id><published>2008-02-17T21:19:00.004+05:30</published><updated>2008-02-17T21:37:37.184+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="delete"/><category scheme="http://www.blogger.com/atom/ns#" term="new"/><category scheme="http://www.blogger.com/atom/ns#" term="unsized arrays"/><category scheme="http://www.blogger.com/atom/ns#" term="vector"/><category scheme="http://www.blogger.com/atom/ns#" term="zero sized array"/><title type='text'>Zero-sized arrays</title><content type='html'>It is valid to do the below:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T * ptr = new T[0];&lt;br /&gt;&lt;br /&gt;0 is a perfectly valid input to the array form of new expression. What is the use of it, you may ask. No use as far as the array is concerned. What use is an array if it does not have any members? What can you possibly do with it? Nothing! Right, you cannot do anything with it but the statement above being valid is atleast a little bit helpful.&lt;br /&gt;&lt;br /&gt;It allows you to have code like this:&lt;br /&gt;&lt;br /&gt;void f(size_t n) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     int * ptr = new int[n]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     //... &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     delete[] ptr; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;instead of: &lt;br /&gt;&lt;br /&gt;void f(size_t n) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   if (n&amp;gt;0) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     int * ptr = new int[n]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     //... &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     delete[] ptr; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   } &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;No other use though as said earlier, because since it has zero elements, you cannot do anything with it. &lt;br /&gt;&lt;br /&gt;This reminds of another peculiar extension related to zero sized/unsized arrays. VC++ has an extension which makes use of zero sized arrays as the last member of structures. For example, see this: &lt;br /&gt;&lt;br /&gt;#include&amp;lt;cstdlib&amp;gt; &lt;br /&gt;#include&amp;lt;iostream&amp;gt; &lt;br /&gt;&lt;br /&gt;struct test &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   int cb; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   int buf[]; &lt;br /&gt;}; &lt;br /&gt;&lt;br /&gt;int main() &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   test* bb; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   int length = 10; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   bb = (test*) malloc(sizeof(test)+sizeof(int)*length); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   bb-&amp;gt;cb = length; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   //fill buf with length int items or can copy from another array for length elements&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   bb-&amp;gt;buf[i]=10; //i should be less than length &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   //OR-------- &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   test aa = {10, {1,10,22,32}}; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   std::cout &amp;lt;&amp;lt; aa.buf[2]; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;Since the zero size member is in there, there are few restrictions as well. You cannot create an array of the test struct. You can mimic that though like this: &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//create an array of length 10 of test pointers &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;test * ptr[10]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//set each of the pointers to individual elements created as above &lt;br /&gt;&lt;br /&gt;Generally, you would be better off keeping a pointer member but it is &lt;br /&gt;worth noting the presence of such an extension. See for details : &lt;br /&gt;&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms858712.aspx&quot;&gt;Unsized arrays&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The rationale as per msdn is saving the runtime pointer dereferences and that is not specific to C. How big that overhead is, with respect to the application in order to make a choice to this extension, is a different story altogether. You could even implement std::vector&amp;lt;T&amp;gt; using this extension rather than having a pointer to type T! That is, std::vector&amp;lt;T&amp;gt; implementation with VC++ might use this extension but they don&#39;t do so. :-)&lt;br /&gt;&lt;br /&gt;Interesting one, this one... isn&#39;t it? :-)</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/6806285288841477372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/6806285288841477372?isPopup=true' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/6806285288841477372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/6806285288841477372'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/02/zero-sized-arrays.html' title='Zero-sized arrays'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-1902490260054056966</id><published>2008-02-17T11:30:00.003+05:30</published><updated>2008-02-17T11:36:44.395+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="const"/><category scheme="http://www.blogger.com/atom/ns#" term="extern"/><category scheme="http://www.blogger.com/atom/ns#" term="linkage"/><title type='text'>const in C and C++</title><content type='html'>Globals are usually bad but not always. Consider C code that is to be migrated to C++ and has a bunch of global constants. As soon as that code is worked upon and is compiled as C++, those const globals will cause the compiler to start emitting &quot;undefined reference&quot; or similar errors.&lt;br /&gt;&lt;br /&gt;This is because of fundamental different between how const is treated in C and C++ in the context of linkage.&lt;br /&gt;&lt;br /&gt;In C, apart from the fact that const are non-modifiable variables, they are the same as any other variables. In C++, const have different linkage as well. C++ const objects/variables have internal linkage and hence you get unresolved symbol error when you try to access something in a different compilation unit having iternal linkage from another compilation unit.&lt;br /&gt;&lt;br /&gt;The solution is to include the extern declaration following right after you define the const variables, the same one that you put in another files or simply define the variable as extern const instead of just const.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/1902490260054056966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/1902490260054056966?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1902490260054056966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1902490260054056966'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/02/const-in-c-and-c.html' title='const in C and C++'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-2469506537772417600</id><published>2008-02-17T11:10:00.002+05:30</published><updated>2008-02-17T11:30:00.131+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="#ifndef"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="gcc"/><category scheme="http://www.blogger.com/atom/ns#" term="include guards"/><category scheme="http://www.blogger.com/atom/ns#" term="pragma once"/><title type='text'>#pragma once standardized?</title><content type='html'>I have at a few places, where people have mis-heard/mis-read that that #pragma once has been standardized for C++0x. It&#39;s &quot;not&quot;.&lt;br /&gt;&lt;br /&gt;Even gcc has it labelled as an obsolete feature (for a couple of years now) - &lt;a href=&quot;http://gcc.gnu.org/onlinedocs/gcc-4.2.3/cpp/Obsolete-once_002donly-headers.html#Obsolete-once_002donly-headers&quot;&gt;Obsolete once-only headers&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Since, it is not standard in the first place, one should avoid using it. The standard include guards &quot;#ifndef&quot; should the choice and with good compiler support, these are as efficient as the promise made by #pragma once. Plus they are guaranteed to be portable.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/2469506537772417600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/2469506537772417600?isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/2469506537772417600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/2469506537772417600'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/02/pragma-once-standardized.html' title='#pragma once standardized?'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-3076436058068632510</id><published>2008-02-17T10:58:00.002+05:30</published><updated>2008-02-17T11:08:56.482+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="fstream"/><category scheme="http://www.blogger.com/atom/ns#" term="rdbuf"/><category scheme="http://www.blogger.com/atom/ns#" term="stringstream"/><title type='text'>Reading file all at once</title><content type='html'>Few times, you would want to read the whole file in one go, not line by line, not by a fixed buffer size. Here&#39;s a way to get that done:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::fstream ifs(&quot;filename.txt&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!ifs)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   std::stringstream oss;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   oss &lt;&lt; ifs.rdbuf();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;As simple as that. The contents of the file are moved (re-directed) to the stringstream. The same code can be used to make copies of files. You would need to replace the stringstream object with an fstream one though.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/3076436058068632510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/3076436058068632510?isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3076436058068632510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/3076436058068632510'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2008/02/reading-file-all-at-once.html' title='Reading file all at once'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-8148735209839783744</id><published>2007-11-29T18:44:00.000+05:30</published><updated>2007-11-29T19:39:47.401+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="base class"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="constructors"/><category scheme="http://www.blogger.com/atom/ns#" term="coupling"/><category scheme="http://www.blogger.com/atom/ns#" term="derived class"/><category scheme="http://www.blogger.com/atom/ns#" term="Initialization lists"/><title type='text'>Initialization lists and base class members</title><content type='html'>Just some thoughts upon a question that I ran across, raised about, why you could not initialize base class members in derived classes. Put it another way, why could you not use the base class data members in derived class&#39; initialization lists. Simplest reason - the standards, the language rules don&#39;t allow it. But let&#39;s have some fun with the &quot;what-if&quot;s.&lt;br /&gt;&lt;br /&gt;One reason that struck me almost as a first thought, that the data member could be private in which case, you won&#39;t have access to it in the derived class. But what if it is public or protected? Let us take an example:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class Base&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Base(){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Base(int member_) : member (member_){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int member;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//other members&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class Derived : public Base&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Derived(int member_) : member(member_){} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//other members&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Derived derivedObject(10);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You would have expected it to work since the base member is accessible in the derived class, it being public. After all, it is perfectly okay if you used it in the derived class constructor body! What is so special about initialization lists that only direct base classes, virtual bases and the containing class&#39; data members can only appear?&lt;br /&gt;&lt;br /&gt;You might think that the base class object might not have been allocated or does not exist at all while in the initialization list of the derived class and hence it is not allowed to do that. But that reasoning would be flawed. Why? For the following reason (quoting section 12.6.2 (5) from the standards):&lt;br /&gt;&lt;br /&gt;Initialization shall proceed in the following order:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;— First, and only for the constructor of the most derived class as &lt;br /&gt;    described below, virtual base classes shall be initialized in the &lt;br /&gt;    order they appear on a depth-first left-to-right traversal of the &lt;br /&gt;    directed acyclic graph of base classes, where “left-to-right” is &lt;br /&gt;    the order of appearance of the base class names in the derived &lt;br /&gt;    class base-specifierlist.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;— Then, direct base classes shall be initialized in declaration order &lt;br /&gt;    as they appear in the base-specifier-list (regardless of the order &lt;br /&gt;    of the mem-initializers).&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;— Then, non-static data members shall be initialized in the order &lt;br /&gt;    they were declared in the class definition (again regardless of &lt;br /&gt;    the order of the mem-initializers).&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;— Finally, the body of the constructor is executed.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ Note: the declaration order is mandated to ensure that base and &lt;br /&gt;   member subobjects are destroyed in the reverse order of initialization. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;—end note ]&lt;br /&gt;&lt;br /&gt;So, the base is already initialized before anything else happens in the initialization list. What could be the reason then? The reason probably is that it does not make sense! Once the base constructor has initialized the base member, the derived class initializing it does not make sense. How can one thing be initialized twice? The second time, it has to be an assignment.&lt;br /&gt;&lt;br /&gt;But again, that holds true just for non-POD members. For the object being constructed in the above code, via default constructor of the base class, the POD member &quot;member&quot; remains uninitialized! It will have an indeterminate value. So, it won&#39;t be double initialization, would it? It would be initialized just once and that from the derived class constructor (initialization list). &lt;br /&gt;&lt;br /&gt;Now, consider there were a further derived class that publicly derived from the above &quot;Derived&quot; class having the same member initialization syntax. Now, that makes it two. This could probably have been dealt with some complication set of rules but why add that logical overhead? &lt;br /&gt;&lt;br /&gt;That is not all though. The *rules* can get more complex. The consideration of different access specifiers (private/protected), different inheritance types (private/protected), an explicit constuctor call that too initializes the member, virtual bases, different treatment for non-POD and POD types and what not. Things just start to get too complex and dirty if you allow that. &lt;br /&gt;&lt;br /&gt;Simply speaking, base class members should be the base class&#39; responsibility and derived class should only be concerned with the construction abstraction provided by the base classes in form of the base constructors and their initialization lists. Making things more coupled is always a sign of bad design choice where things just start to fall apart as soon as something changes. That is not good code.&lt;br /&gt;&lt;br /&gt;To make things clear and simpler, it&#39;s best said and accepted that the standard does not allow it for initialization lists to take up the responsibility of initializing base class members, just the immediate bases, virtual bases and class&#39; members.&lt;br /&gt;&lt;br /&gt;Have fun... Cheers!</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/8148735209839783744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/8148735209839783744?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/8148735209839783744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/8148735209839783744'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/11/initialization-lists-and-base-class.html' title='Initialization lists and base class members'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-767606579039622911</id><published>2007-11-24T13:44:00.000+05:30</published><updated>2007-11-24T15:38:43.106+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="Multithreading"/><category scheme="http://www.blogger.com/atom/ns#" term="TBB"/><title type='text'>Threading Building Blocks</title><content type='html'>Just for a quick note. Intel recently made their TBB library open source and since it has a different task-based approach to incorporating parallism in C++, it felt interesting. It uses threads internally but keeps the user code away from threads themselves by parallelizing actions/tasks user performs in his/her code. Looks nice, sounds good, since threads are basically a low level detail to achieving benefits of parallel processing and if there can be laid a layer of abstraction that insulates programmers from those details, it could ease out and quicken the developement of parallel processing within applications without getting into the nitty-gritty of threads. Analogously, do we deal with the parallel processing across FPUs?&lt;br /&gt;&lt;br /&gt;Few days back I downloaded the Open Sourced Intel Threading Building Blocks library and started to test a few samples with it.&lt;br /&gt;&lt;br /&gt;One of the sample solution in there was using parallel_for algorithm (parallel_for.h). It was giving me a fatal error that the file affinity.h could not be found. It did not exist! This file was being included in parallel_for.h.&lt;br /&gt;&lt;br /&gt;After much of searching and going quickly through the docs, I could not find the reason but I luckily bumped into a thread in the libraries discussion forum. Where one user complained of the file missing from the development release.&lt;br /&gt;&lt;br /&gt;The suggestion to fix this was:&lt;br /&gt;&lt;br /&gt;1. Either comment out the include.&lt;br /&gt;2. Add an empty file in the include path.&lt;br /&gt;&lt;br /&gt;This resolves the compilation issue but why keep such an include anyway? It wastes a bit of time of everyone who is new to the project and wants to get quickly building out samples and testing/debugging and seeing the library in action. Probably they will fix this soon.&lt;br /&gt;&lt;br /&gt;More information can be found here - &lt;a href=&quot;http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30243228.aspx&quot;&gt;Latest Developer Release Missing affinity.h&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Hope this helps anyone who is starting out on TBB and falls upon the same problem until that header comes alive in the project while I will go back to experimenting more with it. Good luck and have fun! :)</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/767606579039622911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/767606579039622911?isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/767606579039622911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/767606579039622911'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/11/intel-threading-building-blocks.html' title='Threading Building Blocks'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-1527551916995222075</id><published>2007-09-14T09:57:00.000+05:30</published><updated>2007-09-14T10:04:33.524+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="boost"/><category scheme="http://www.blogger.com/atom/ns#" term="boost::any"/><category scheme="http://www.blogger.com/atom/ns#" term="heterogenous containers"/><category scheme="http://www.blogger.com/atom/ns#" term="templates"/><category scheme="http://www.blogger.com/atom/ns#" term="type-safe"/><title type='text'>boost::any</title><content type='html'>boost::any is a strong concept and a much better replacement to void* to hold any type of data. You can make heterogenous containers using it as well. Let us see how it works in a very simplified way. The idea is to have a template class that can wrap all types and a value associated with that type. Something like this:&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;class HoldData&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T t;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;And then having a base class from which this wrapper would derive, so the above becomes adding a constructor that needs the type to be stored in it to be copy constructible:&lt;br /&gt;&lt;br /&gt;class BaseHolder&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;virtual ~BaseHolder(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;class HoldData : public BaseHolder&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HoldData(const T&amp; t_) : t(t_){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T t;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Now, you would have a class, name it Variant that will take inputs of all types and then has a pointer to this wrapper&#39;s base type. So, now you have (including above classes):&lt;br /&gt;&lt;br /&gt;class BaseHolder&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;virtual ~BaseHolder(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;class HoldData : public BaseHolder&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HoldData(const T&amp; t_) : t(t_){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T t;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Variant&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template&amp;lt;typename T&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Variant(const T&amp; t) : data(new HoldData&amp;lt;T&amp;gt;(t)){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;~Variant(){delete data;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BaseHolder* data;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;You construct the corresponding type&#39;s wrapper objects and save their pointer into the another class that you call variant, that can hold and help retrieve any data type and does not lose the respective type information. That is actually what boost::any does. Take a look at the code here - &lt;a href=&quot;http://www.boost.org/boost/any.hpp&quot;&gt;boost::any code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The documentation on it can be found here - &lt;a href=&quot;http://www.boost.org/doc/html/any.html&quot;&gt;boost::any documentation&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/1527551916995222075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/1527551916995222075?isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1527551916995222075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/1527551916995222075'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/09/boostany.html' title='boost::any'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-7039036990245991487</id><published>2007-08-01T13:15:00.000+05:30</published><updated>2007-08-01T13:20:05.068+05:30</updated><title type='text'>Policies and Traits</title><content type='html'>Policies - I got to know about them from Andrei&#39;s Modern C++ Design book. If there are different orthogonal (independent) ways to achieve a particular functionality, they are good candidates to be classified as policies and we can write types based on those policies. Policies, in general, are compile time variants of strategies as in Strategy pattern. For example, the allocator template parameter to STL classes could be said as an allocation policy - the default being std::allocator&amp;lt;T&amp;gt;.&lt;br /&gt;&lt;br /&gt;Traits - I understand them as not achieve anything for the class or the type (policies do achieve some functionality for their host class). They basically tell something about the type. &lt;br /&gt;&lt;br /&gt;For example, boost::type_traits (is_pod, is_fundamental, is_derived_of, is_polymorphic). All these help in knowing something about the type. They are not orthoganal (independent, de-coupled ) ways of doing something or exposing some functionality. They don&#39;t add something to the definition of the type rather they provide for a set of information. &lt;br /&gt;&lt;br /&gt;If I may take another example : std::char_traits&amp;lt;charT&amp;gt;. They tell something about the type via a few typedefs but they also have functions that tell about how to compare, assign, find length, etc. These &quot;add&quot; to the definition of the type in the context (context meaning whatever char_traits is passed to make a string type out of basic_string). char_traits looks to include policies, looks like a collection of policies. It provides policies to compare, assign and find length. A basic_string of character type &quot;char&quot; can have a different definitions of (or ways to do) comparison. I can provide a specialization or a traits class of my own where I change the compare to be case insensitive. This seems like a policy because they are two different ways to achieve the same objective, to fulfil a requirement, to expose a functionality, to define the working in a specific context. I can define that policy as &quot;A compare policy that must expose a Compare member function, callable with 2 char_type* types and a size_t argument signifying number of elements to compare and returns a boolean result&quot;.&lt;br /&gt;&lt;br /&gt;As compared to char_traits if I take std::numeric_limits : this can be said to be a trait (or a collection of traits). They tell about what max() for a type is, what epsilon() for a type is. They are not policies. They don&#39;t achieve some behaviour but they may represent how types should/may behave or what properties they have. I cannot specialize traits. That would be wrong. Policies? Of course, specialize it, rename it.&lt;br /&gt;&lt;br /&gt;Policies and traits are both compile time features. Type traits at runtime would be RTTI. Policies at runtime would be strategies. None of those need necessarily be templates though.&lt;br /&gt;&lt;br /&gt;Based on the above understanding, I would be right in thinking that basic_string template would have been better defined as:&lt;br /&gt;&lt;br /&gt;template&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class CharT, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template &amp;lt;class&amp;gt; CharTPolicyCollection, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template &amp;lt;class&amp;gt; AllocationPolicy&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class basic_string : &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public CharTPolicyCollection&amp;lt;CharT&amp;gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public AllocationPolicy&amp;lt;CharT&amp;gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//members&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;because otherwise, if you wrote something like this:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;typedef std::basic_string&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;char, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::char_traits&amp;lt;wchar_t&amp;gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::allocator&amp;lt;wchar_t&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mystrtype;&lt;br /&gt;        &lt;br /&gt;.. and you would not be wrong. The only problem being it will not work as expected for a sequence of char (i.e. like std::string). This problem exists because the basic_string doesn&#39;t use template template parameters. Had they used it, incompatible policies could not be clubbed with the host class to form a wierd type.&lt;br /&gt;&lt;br /&gt;You should have protected CharTPolicyCollection and AllocationPolicy destructors if you are worried about the public inheriatnce and destruction via the base policy class pointers. Their virtual destructor would be also a solution but would be an unwanted overhead of the v-table. The typedefs there in std::char_traits though can be said to be traits, may be.&lt;br /&gt;&lt;br /&gt;This is another reason why std::basic_string is not a very good design. The first being an overly loaded public interface.&lt;br /&gt;&lt;br /&gt;Cya!</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/7039036990245991487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/7039036990245991487?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/7039036990245991487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/7039036990245991487'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/08/policies-and-traits.html' title='Policies and Traits'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-4820701651508138179</id><published>2007-07-11T10:47:00.000+05:30</published><updated>2007-10-03T10:32:09.698+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="auto_ptr"/><category scheme="http://www.blogger.com/atom/ns#" term="boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="custom deleters"/><category scheme="http://www.blogger.com/atom/ns#" term="deque"/><category scheme="http://www.blogger.com/atom/ns#" term="memory leak"/><category scheme="http://www.blogger.com/atom/ns#" term="memory management"/><category scheme="http://www.blogger.com/atom/ns#" term="new"/><category scheme="http://www.blogger.com/atom/ns#" term="shared_ptr"/><category scheme="http://www.blogger.com/atom/ns#" term="smart pointers"/><category scheme="http://www.blogger.com/atom/ns#" term="undefined behaviour"/><category scheme="http://www.blogger.com/atom/ns#" term="vector"/><title type='text'>Handling dynamic array allocations</title><content type='html'>One of the recent questions on the forums, that I answered to recently, was related to using std::auto_ptr&amp;lt;&amp;gt; with allocations from array form of new. The need to know was - if the following would work?&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::auto_ptr&amp;lt;int&amp;gt; ptr(new int[100]);&lt;br /&gt;&lt;br /&gt;if not then why not?&lt;br /&gt;&lt;br /&gt;The answer was simple if one knows what std::auto_ptr&amp;lt;&amp;gt; is good for, what its deleter is. std::auto_ptr&amp;lt;&amp;gt; uses delete operator to destruct owned pointer (pointing to a dynamic allocation made via new operator). So, it comes down to mixing of constructs like array form of new and simple delete. That is undefined behaviour as per the standards. You can read up more about these operators here - &lt;a href=&quot;http://learningcppisfun.blogspot.com/2007/04/free-new-delete-malloc.html&quot;&gt;Free New, Delete Malloc&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;By design, the standard auto_ptr&amp;lt;&amp;gt; smart pointer is not suitable for dynamic array allocations. There can be many alternatives though. Few of those are as listed below:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Avoid self memory management and instead use std::vector&amp;lt;&amp;gt; / std::deque&amp;lt;&amp;gt; for dynamic arrays.&lt;/li&gt;&lt;li&gt;Use boost::scoped_array&amp;lt;&amp;gt;/boost::shared_array&amp;lt;&amp;gt;/boost::shared_ptr&amp;lt;&amp;gt; with a custom deleter (delete[]) passed in.&lt;/li&gt;&lt;li&gt;Write your own smart pointer : auto_ptr_array&amp;lt;&amp;gt; (same implementation as std::auto_ptr&amp;lt;&amp;gt;) just that it uses array form of delete instead of delete.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;For the second point above - you can read more about custom deleters and shared_ptr&amp;lt;&amp;gt; here - &lt;a href=&quot;http://learningcppisfun.blogspot.com/2007/05/custom-deleters-with-smart-pointers.html&quot;&gt;Custom deleters with smart pointers&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;A boost::shared_array&amp;lt;&amp;gt;/boost::shared_ptr&amp;lt;&amp;gt; might not be the right choice if you don&#39;t want the reference count overhead of shared ownership which really should not be required when talking about auto_ptr&amp;lt;&amp;gt;s but if that&#39;s not an issue to worry about, it should work fine.&lt;br /&gt;&lt;br /&gt;Another confusion arose, why doesn&#39;t std::auto_ptr&amp;lt;&amp;gt; do a delete[] instead of delete? Well, again, because it is not intended for array allocations. It would hence not work for singular objects created on the free store. This is because of the way delete[] might be implemented by the compiler.&lt;br /&gt;&lt;br /&gt;There can be many ways in which delete[] could be implemented. Two of those are explained here - &lt;a href=&quot;http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.14&quot;&gt;How does delete[] know how many elements to destroy?&lt;/a&gt; It is important for delete[] to know how many elements to destroy particularly since it is used with non-POD types as well and there, the destructor calls are necessary to be made for each of the to-be-destructed elements of the array.&lt;br /&gt;&lt;br /&gt;The first method listed in the C++ FAQ Lite uses an extra allocation to remember the size you ask for at the runtime, if you used delete[] for single allocations, the compiler might try to interpret the block before the pointer you call it on as being size but since that was not allocated in the first place (new[] was not used!) - expect anything to happen, a crash or any other form of runtime error (depending upon how that error is translated on a particular system).&lt;br /&gt;&lt;br /&gt;For the second, where array length association might not exist, it could cause anything depending upon a number of factors about the compiler implementation. One such possibility is, it could leave the variable uninitialized (yeah, its a bad thing, may not actually be happening, but who knows for sure about all compilers? We are just talking of possibilities here) - in which case the size could be anything - even 2 which goes beyond the buffer you allocated and again can cause any fault to the system/system free store. If the size is initialized to 0, it could leave the memory untouched and hence lost resulting in a leak. Memory leaks can be really dangerous particularly on systems that don&#39;t reclaim the leaked blocks by a process.&lt;br /&gt;&lt;br /&gt;So, when the standard says, its undefined behaviour, it can result in anything. Worse could happen and thinking about these issues beyond the statement of &quot;undefined behaviour&quot; is rather silly. There can be many such &quot;interesting&quot; stories that one can write up. The key is, use std::auto_ptr&amp;lt;&amp;gt; what it is suited for, use delete/delete[] what they are suited for. Mixing them is really dangerous.&lt;br /&gt;&lt;br /&gt;There is a peculiarity to note though. If you do the allocation for the single element using array form of new - you could use delete[] for that single element. That is:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int * ptr = new int[1];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delete[] ptr; //OK&lt;br /&gt;&lt;br /&gt;Well, not really a peculiarity, but yeah, something to take note of.&lt;br /&gt;&lt;br /&gt;Forum reference : &lt;a href=&quot;http://www.codeguru.com/forum/showthread.php?t=428317&quot;&gt;What&#39;s wrong with std::auto_ptr&amp;lt;int&amp;gt; ptr(new int[100]);? &lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/4820701651508138179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/4820701651508138179?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/4820701651508138179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/4820701651508138179'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/07/handling-dynamic-array-allocations.html' title='Handling dynamic array allocations'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-8316997196999210409</id><published>2007-07-03T12:05:00.000+05:30</published><updated>2007-10-03T19:12:42.917+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="lexical_cast"/><category scheme="http://www.blogger.com/atom/ns#" term="pointers"/><category scheme="http://www.blogger.com/atom/ns#" term="references"/><category scheme="http://www.blogger.com/atom/ns#" term="serialization"/><title type='text'>Pointers or references (function arguments)</title><content type='html'>There is always a long discussion whenever a choice between a pointer or a reference is to be made. Be it when deciding function arguments (part of the interfaces) or when creating objects and working with them.&lt;br /&gt;&lt;br /&gt;The fundamental difference comes around the NULLability of the pointers that helps decide if a reference should be used or a pointers. Certain people are also of the mind that having a pointer in the interface is a good signal to tell the caller that the value can be modified. But so can a reference tell you (of course, you would need to look at the interface). The point is further weakened by the const-keyword. What if the pointer is to a const? There are certain more interesting points to think upon that I touch above here.&lt;br /&gt;&lt;br /&gt;Pointers can point to raw memory and not just valid or invalid or NULL objects. In object construction, there is are two steps of memory allocation and then construction via the constructor call. You would not want pass the memory being referred/pointed to as a reference when the second phase is yet to complete. For example, with boost serialization: &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// load data required for construction and invoke constructor in place &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template&amp;lt;class Archive, class T&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inline void load_construct_data( &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Archive &amp; ar, T * t, const unsigned int file_version ){ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// default just uses the default constructor to initialize &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// previously allocated memory. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;::new(t)T(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&lt;br /&gt;In the above snippet, passing the second object by reference would not make sense because the object is not yet fully constructed. For such lazy construction scenarios, a pointer parameter type looks more clearer as I would not want to associate a reference to a not-fully-constructed object. And quite reasonably, I am yet to see any code doing this.&lt;br /&gt;&lt;br /&gt;In addition to that, pointers support arithematic on them, references don&#39;t. So, if there is such a need in a function, passing a reference makes it much less clearer. A pointer is more intuitive and natural. A reference would mean a single object (atleast I haven&#39;t seen anyone working with a reference to the first element of an array - containers aside - but still we work with iterators or random access there which is closer to pointer semantics). To me, it would look really poor choice to have a reference passed as a start element for an array. I have never seen such code. In this context, think upon : why don&#39;t STL algorithms take references? They could have had got back to pointers? They take iterators (and pointers) and it is not that all of them tend to modify the objects always. &lt;br /&gt;&lt;br /&gt;Whole of memory management constructs in C and C++ revolve around pointers. new returns a pointer, malloc returns a pointer, free and delete work on pointers. So, preserve the naturality of expressions/statements, a pointer is a better choice. Similarly, references can be the right choice in many cases based on the same ground. &lt;br /&gt;&lt;br /&gt;For a piece of C++ code that has to deal with C, or for that matter with any other language interoperability, pointers have no alternative. Why make an unnecessary transformation from pointer to reference and then back to pointer in such scenarios? &lt;br /&gt;&lt;br /&gt;There are certain restrictions sometimes, for example exception handling disallowed in the code. In those scenario&#39; of nothrow(), there are operations that throw with references (for example, dynamic_cast&amp;lt;&amp;gt; as compared to pointers. What would be more natural choice - a pointer argument or a reference? Well, that could be argued &lt;br /&gt;upon depending on how the object was being declared and used prior to it but if this happens inside a function (for the interface writer), I would expect it to take a pointer than a reference. When you return the result of the cast, you would not want to dereference it and pass it back. All this pointer to reference transformation makes it look a lot less cleaner. Not to mention the case of a NULL return if the cast fails. &lt;br /&gt;&lt;br /&gt;Now, I wonder why boost::lexical_cast&amp;lt;&amp;gt; doesn&#39;t take a pointer. For example: &lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;template&amp;lt;typename Target, typename Source&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Target lexical_cast(const Source &amp;arg) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{ &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;typedef typename detail::array_to_pointer_decay&amp;lt;Source&amp;gt;::type NewSource; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;detail::lexical_stream&amp;lt;Target, NewSource&amp;gt; interpreter; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Target result; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if(!(interpreter &amp;lt;&amp;lt; arg &amp;&amp; interpreter &amp;gt;&amp;gt; result)) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;throw_exception(bad_lexical_cast(typeid(NewSource), typeid(Target))); &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return result; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;} &lt;br /&gt;&lt;br /&gt;This template would generate multiple instantiations for a char array of different sizes. That is plain code bloat. Boost writers prevent the lexical_stream&amp;lt;&amp;gt; from bloating by that decay trick but the lexical_cast template itself isn&#39;t saved. It needs compiler optimizations to prevent that (with VS2005 and gcc 4.1 that I know &lt;br /&gt;of). That would have had been avoided had it accepted the Source &lt;br /&gt;argument as a pointer in which case, all arrays passed would have had &lt;br /&gt;automatically decayed to pointer. No hacks would have had been &lt;br /&gt;required! &lt;br /&gt;&lt;br /&gt;On the initial point of if a pointer/reference signalling modification inside the function - what if pointers are themselves passed by reference? How clearer would the code be from the calling point (for the caller)? :-) &lt;br /&gt;&lt;br /&gt;What I feel is the natural semantics should be respected. Be it a reference or a pointer, it does not matter as long as the code does what it needs to do (checking for non-NULL pointers, not change an object) and the restrictions can be implemented using any of those. References provide ease to accessing members and you don&#39;t always need the &#39;-&amp;gt;&#39; operator which can be a typing pain sometimes. :) I am with the C++ FAQ Lite on this - &quot;Use references where you can, pointers where you have to.&quot; A little juggling between them is not really a concern except when it becomes too much causing loss of code clarity/readability and may be performance at some point of time.</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/8316997196999210409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/8316997196999210409?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/8316997196999210409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/8316997196999210409'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/07/pointers-or-references-function.html' title='Pointers or references (function arguments)'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-4676763174410304170</id><published>2007-07-03T10:45:00.000+05:30</published><updated>2007-07-08T12:31:02.059+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="binding to reference to non-const"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="conforming and non-conforming extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="non-standard extensions"/><title type='text'>Conforming/Non-conforming non-standard extensions</title><content type='html'>Recently, I came across this piece of code on the forums where the original poster was claiming to be compiling fine with VS2005 C++ compiler.&lt;br /&gt;&lt;br /&gt;[CODE]&lt;br /&gt;class X{};&lt;br /&gt;X f(){&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return X();&lt;br /&gt;}&lt;br /&gt;void g(X&amp;){}&lt;br /&gt;int main(){&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g(f());&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Quite puzzling, since this is strictly not allowed as per the standards - a temporary cannot be bound to a non-const reference and that is what is actually happening here - the temporary X object returned from f() is being passed to g() that accepts a reference to non-const X.&lt;br /&gt;&lt;br /&gt;Could it be because there is no assembly instruction generated for the call in main() since g() is empty? I think not. Any C++ code has to be legal first to get successfully compiled. Optimizations and code generation happens later. One cannot expect a non-compilable copy constructor to be optimized out owing to RVO/NRVO and hence compile fine. That is just wrong. The compiler has to pass the code for semantic validity. The C++ standard lays down the rules around the syntax of a valid C++ program and it must be respected by a conforming compiler. If a particular construct is ill-formed, the compiler may or may not proceed ahead. It would not generate the compiled code though, as the application has ill-formed C++, but it may proceed with the compilation in order to accumulate other errors that might be caught. Imagine a compiler that stopped compiling at the occurence of the very first error. It would make the compilation task so much more repeatative. Not that the following errors are always relevant to different errors but it helps.&lt;br /&gt;&lt;br /&gt;Anyways, back to the topic - it came out to be a non-standard extension. Vendors can provide non-standard extensions as the standard allows it. Here is what the standard has to say around non-standard extensions [section : 1.4 (8)]:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&quot;A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.&quot;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;And this extension (that violates the standards rule directly) actually fulfils the above except that the diagnostic (error or warning) is not there until a warning level 4.&lt;br /&gt;&lt;br /&gt;Here are some additional relevant quotes from the standards [section : 1.4 (2)]:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Although this International Standard states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;— If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute that program.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;— If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message, except that&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;— If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;This extension falls in the second category mentioned above in that it violates the rules of the IS and the IS does not suggest &quot;no diagnosis required&quot;. So, the compiler becomes conforming around this extension at warning level 4 but non-conforming at less stricted levels. My recommendation is to never use this extension. If you are going to modify an object, making a named copy of it, would suffice.&lt;br /&gt;&lt;br /&gt;References: &lt;a href=&quot;http://www.codeguru.com/forum/showthread.php?t=427103&quot;&gt;Codeguru thread - Binding a temporary to a reference to non-const&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/4676763174410304170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/4676763174410304170?isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/4676763174410304170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/4676763174410304170'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/07/conformingnon-conforming-non-standard.html' title='Conforming/Non-conforming non-standard extensions'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14389137.post-4799876266330217597</id><published>2007-05-07T10:30:00.001+05:30</published><updated>2010-05-07T07:52:21.349+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="auto_ptr"/><category scheme="http://www.blogger.com/atom/ns#" term="boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="custom deleters"/><category scheme="http://www.blogger.com/atom/ns#" term="memory leak"/><category scheme="http://www.blogger.com/atom/ns#" term="memory management"/><category scheme="http://www.blogger.com/atom/ns#" term="smart pointers"/><title type='text'>Custom deleters with smart pointers</title><content type='html'>There is just one smart pointer as part of the standard C++ library as of now (excluding the tr1 and proposals). That is the &lt;a href=&quot;http://learningcppisfun.blogspot.com/2005/07/autoptr-and-their-usability-with-stl.html&quot;&gt;std::auto_ptr&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is crucial to know that you can only use it for allocations made via the new operator. It neither handles, the allocations made via the array form of new or malloc or any other allocation routine provided, for that matter. &lt;br /&gt;&lt;br /&gt;How can you extend it to be able to use it with those? Basically, you can&#39;t. There are an option though - you lay down your own version of auto_ptrs specific to those which have the delete call replaced by free/delete[]/or the relevant deleter. This will ask for writing down multiple classes for them and using them as appropriate. There is another way to extend it but before that let&#39;s look at how boost::shared_ptr handles it.&lt;br /&gt;&lt;br /&gt;Boost shared_ptr has a concept for a custom deleter. The deleter would operate on the pointer (when the reference count drops to 0 - remembers the ownership is shared!) and the effect should be that of freeing the resource. The following is an illustration:&lt;br /&gt;&lt;br /&gt;[CODE]&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;struct mallocDeleter&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void operator() (T*&amp; ptr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (ptr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;free(ptr);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ptr=NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;};&lt;br /&gt;void somefunction()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyType* ptr = getAllocatedPointer();//returns pointer to memory allocated by malloc&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shared_ptr&amp;lt;MyType, mallocDeleter&amp;lt;MyType&amp;gt; &amp;gt;object(ptr, mallocDeleter());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//scope ends shared_ptr&#39;s destructor gets called that then called mallocDeleter(ptr) - The default deleter is &quot;delete&quot;.&lt;br /&gt;&lt;br /&gt;Notice, how this expresses the flexibility. You could have acquired any other resource and would have wrapped it inside a shared_ptr and would provide the deleter to free that resource. For example, a File Handle - on which the custom deleter calls close (for C++ fstream objects, you don&#39;t need that - they already exploit RAII). Or, a db connection handle, for which the deleter would handle closing it. Just about anything that is manually allocated! Amazing how the ability to provide the deleter makes this smartness so generic.&lt;br /&gt;&lt;br /&gt;I wonder why the auto_ptr or the boost scoped_ptr don&#39;t provide this ability. RAII is truely magic and takes care of resource leak issues so well. &lt;br /&gt;&lt;br /&gt;Cheers!</content><link rel='replies' type='application/atom+xml' href='http://learningcppisfun.blogspot.com/feeds/4799876266330217597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/14389137/4799876266330217597?isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/4799876266330217597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14389137/posts/default/4799876266330217597'/><link rel='alternate' type='text/html' href='http://learningcppisfun.blogspot.com/2007/05/custom-deleters-with-smart-pointers.html' title='Custom deleters with smart pointers'/><author><name>abnegator</name><uri>http://www.blogger.com/profile/09139822935584399971</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry></feed>