{"id":4024,"date":"2019-01-13T14:00:09","date_gmt":"2019-01-13T13:00:09","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=4024"},"modified":"2019-01-13T14:00:09","modified_gmt":"2019-01-13T13:00:09","slug":"c-guns-wshadow-for-constructor-arguments","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=4024","title":{"rendered":"C++ Guns: -Wshadow for constructor arguments"},"content":{"rendered":"<p><em>-Wshadow<\/em> is not that bad. We live in a modern world and don't use C if we can use C++ with a better defined scope and namespaces. So we can catch more errors on compile time.<\/p>\n<p>First: what kind or errors can be detected with <em>-Werror=shadow<\/em> <\/p>\n<blockquote><p>Warn whenever a local variable or type declaration shadows another variable, parameter, type, class member, or whenever a built-in function is shadowed.<\/p><\/blockquote>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nstruct A {\r\n    int i;              \/\/ note: shadowed declaration is here\r\n\r\n    void func(int i) {} \/\/ error: declaration of 'i' shadows a member of 'A' &#x5B;-Werror=shadow]\r\n};\r\n<\/pre>\n<p>This kind or error also occurs if you define a constructor like following code. It defines a type <em>Axis<\/em> which has a <em>title<\/em> and a <em>range<\/em>. The <em>range<\/em> must be valid. The constructor of the <em>Axis<\/em> <strong>does<\/strong> something. So aggregate initialization is not possible. <\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nstruct Axis {\r\n    string title;\r\n    Range range;\r\n\r\n    Axis(string title, Range range) \r\n    : title(title), range(range)       \/\/ error: declaration of 'range' shadows a member of 'Axis'\r\n                                       \/\/ error: declaration of 'title' shadows a member of 'Axis'\r\n    {\r\n        \/\/ check if range is valid, error otherwise\r\n    }\r\n};\r\n<\/pre>\n<p>You can, of course, rename the constructor arguments or member variables. But that is not nice and results in either ugly code or a less proper interface. <\/p>\n<p>The right solution is to split your type into two. One which only store data and another which does something with that data. Let's call the data-type AxisData. Try again:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nstruct Axis {\r\n    struct AxisData {\r\n        string title;\r\n        Range range;\r\n    };\r\n\r\n    AxisData d;\r\n\r\n    Axis(string title, Range range) \r\n    : d{title, range}\r\n    {\r\n        \/\/ check if range.isValid()\r\n    }\r\n};\r\n<\/pre>\n<p>No more errors! The extra variable <em>d<\/em> is no overhead, as you can see in my <a href=\"http:\/\/roboblog.fatal-fury.de\/?p=4016\">previous post<\/a>.<br \/>\nTo hide this implementation details from the programmer, provide some access function and switch from <em>struct<\/em> to <em>class<\/em> because <em>Axis<\/em> is now a type which manage it's data.<\/p>\n<p>So this is the (final, add some references) implementation:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nclass Axis {\r\n    struct AxisData {\r\n        string title;\r\n        Range range;\r\n    };\r\n\r\n    AxisData d;\r\n\r\npublic:\r\n\r\n    Axis(string title, Range range) \r\n    : d{title, range}\r\n    {\r\n        \/\/ check if range.isValid()\r\n    }\r\n\r\n    string title() const {\r\n        return d.title;\r\n    }\r\n\r\n    Range range() const {\r\n        return d.range;\r\n    }\r\n};\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>-Wshadow is not that bad. We live in a modern world and don't use C if we can use C++ with a better defined scope and namespaces. So we can catch more errors on compile time. First: what kind or errors can be detected with -Werror=shadow Warn whenever a local variable or type declaration shadows [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17],"class_list":["post-4024","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-cpp"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/4024","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4024"}],"version-history":[{"count":7,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/4024\/revisions"}],"predecessor-version":[{"id":4031,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/4024\/revisions\/4031"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4024"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}