{"id":716,"date":"2019-12-30T14:40:20","date_gmt":"2019-12-30T22:40:20","guid":{"rendered":"http:\/\/209.126.2.187\/?p=716"},"modified":"2019-12-30T15:45:56","modified_gmt":"2019-12-30T23:45:56","slug":"edge-cases-of-namespace-pollution","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2019\/12\/30\/edge-cases-of-namespace-pollution\/","title":{"rendered":"Edge Cases of Namespace Pollution"},"content":{"rendered":"<h2>Summary<\/h2>\n<p>In the <a href=\"http:\/\/161.97.122.139\/index.php\/2019\/02\/14\/namespace-and-using\/\">previous post<\/a>, I introduced the rules of <code>using directives (using namespace std)<\/code> and <code>using declarations (using std::vector)<\/code>. Generally speaking, the rules are good if there is no confliction, in which two <code>using-declarations<\/code> are the same. <\/p>\n<p>As a quick recap, <\/p>\n<ol>\n<li><code>using directives<\/code> are forbidden. Since this directive makes all names from a namespace available. It is a common cause of collisions and unexpected behavior. A <code>using directive<\/code> works since it adds another path into the lookup.\n<pre><code class=\"language-c++\">\/\/ Forbidden -- This pollutes the namespace.\nusing namespace foo;<\/code><\/pre>\n<\/li>\n<li>Use <code>using-declarations<\/code> instead.  <code>using-declarations<\/code> only take the declared name into the current scope; lookup stops here. <\/li>\n<\/ol>\n<p>In this post, I want to add more examples to show the behavior of namespace pollution in some edge cases. <\/p>\n<h2>Conclusion<\/h2>\n<p>Local <code>using-declarations<\/code> are better than global <code>using-declarations<\/code>. <code>Type alias<\/code> like <code>Typedef<\/code> or <code>using mytype = int<\/code> is even better. <\/p>\n<pre><code class=\"language-c++\">#include &lt;ostream&gt;\n\/\/using namespace std; \/\/ NO!\n\/\/using ::std::cout;   \/\/ less bad than using namespace, it can be better if we scope it\n\nusing cw = console_gui::command_window;\n\nvoid boo() {\n    \/\/ console_gui::command_window::append(&quot;text&quot;)\n    cw::append(&quot;text&quot;);\n}\n\nint main(int argc, char** argv) {\n   int rc = do_some_stuff(argc, argv);\n   using ::std::endl;\n   if (rc) { \/\/ print the success report\n      using ::std::cout;\n      cout &lt;&lt; &quot;The test run completed. The return code was &quot; &lt;&lt; rc &lt;&lt; &#039;.&#039; &lt;&lt; endl;\n    } else {\n      using ::std::cerr;\n      cerr &lt;&lt; &quot;Unable to complete the test run.&quot; &lt;&lt; endl;\n    }\n    return 0 == rc;\n}<\/code><\/pre>\n<h2>Details<\/h2>\n<p>There are several edge cases. <\/p>\n<h3>Edge Case 0: The Call is Ambiguous<\/h3>\n<pre><code class=\"language-c++\">namespace T {\n    void flunk(int) { std::cout &lt;&lt; &quot;T&quot;;}\n}\nnamespace V {\n    void flunk(int) { std::cout &lt;&lt; &quot;V&quot;;}\n}\nint main() {\n    \/\/ 1.\n    {\n        using namespace V;\n        using namespace T; \n        flunk(1);\n    }\n    \/\/ 2. \n    {\n        using V::flunk;\n        using T::flunk;\n        flunk(1);\n    }\n}<\/code><\/pre>\n<p>The error happens at the compliation time (note that it is not multiple definition in the linking time, since the symbols are in different namespace). <\/p>\n<pre><code class=\"language-bash\">main.cpp: In function \u2018int main()\u2019:\nmain.cpp: error: call of overloaded \u2018flunk(int)\u2019 is ambiguous\n     flunk(1);<\/code><\/pre>\n<h3>Edge Case 1: Specialization in Confliction<\/h3>\n<p>The global <code>using declarations<\/code> in <a href=\"http:\/\/161.97.122.139\/index.php\/2019\/02\/14\/namespace-and-using\/\">this post<\/a> will result in some weird behavior.<\/p>\n<pre><code class=\"language-c++\">namespace mynamespace {\n    int max(int, int) { return -1;}\n}\n\nusing std::max;\nusing mynamespace::max;\n\nint main() {\n    printf(&quot;%d&quot;, max(1,2)); \/\/ it will print -1\n}<\/code><\/pre>\n<p>Actually it kind-of has &quot;confliction&quot; in this case, it works since the compiler chooses the most specific one as a specialization of the template function <code>max<\/code> in <code>std<\/code>. <\/p>\n<pre><code class=\"language-c++\">namespace mynamespace {\n    template&lt;typename T&gt;\n    T max(T i, T j) { return i;}\n}\nusing std::max;\nusing mynamespace::max;\nint main() {\n    \/\/ 1. error: call of overloaded \u2018max(int, int)\u2019 is ambiguous\n    printf(&quot;%d&quot;, max(1,2));\n}<\/code><\/pre>\n<p>It will result in the same &quot;Ambiguous&quot; error in case 0. <\/p>\n<h3>Edge Case 2: Hide the Lookup<\/h3>\n<p>If a local variable has the same name as a namespace variable, the namespace variable is hidden, since it won&#8217;t do lookup when the symbol is available included by <code>using-declarations<\/code>. <\/p>\n<pre><code class=\"language-c++\">namespace T {\n    void flunk(int) { std::cout &lt;&lt; &quot;T&quot; &lt;&lt; std::endl; }\n}\nnamespace V {\n    void flunk(int) { std::cout &lt;&lt; &quot;V&quot; &lt;&lt; std::endl; }\n}\nint main() {\n    {\n        using T::flunk;\n        using namespace V;\n        flunk(1); \/\/ T\n    }\n    {\n        using namespace V;\n        using T::flunk;\n        flunk(1); \/\/ T\n    }\n    {\n        using V::flunk;\n        using namespace T;\n        flunk(1); \/\/ V\n    }\n    {\n        using namespace T;\n        using V::flunk;\n        flunk(1); \/\/ V\n    }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Summary In the previous post, I introduced the rules of using directives (using namespace std) and using declarations (using std::vector). Generally speaking, the rules are good if there is no confliction, in which two using-declarations are the same. As a quick recap, using directives are forbidden. Since this directive makes all names from a namespace&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[],"class_list":["post-716","post","type-post","status-publish","format-standard","hentry","category-c","category-proglang"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/716","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=716"}],"version-history":[{"count":9,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/716\/revisions"}],"predecessor-version":[{"id":729,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/716\/revisions\/729"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}