{"id":469,"date":"2009-12-20T01:22:42","date_gmt":"2009-12-20T01:22:42","guid":{"rendered":"http:\/\/kera.name\/articles\/?p=469"},"modified":"2011-06-22T09:29:21","modified_gmt":"2011-06-22T09:29:21","slug":"c-variable-initialisation-how-to-do-it-properly","status":"publish","type":"post","link":"https:\/\/kera.name\/articles\/2009\/12\/c-variable-initialisation-how-to-do-it-properly\/","title":{"rendered":"C++ Variable Initialisation: How To Do It Properly"},"content":{"rendered":"<p>There are two main ways to declare and initialise variables with automatic or static storage in C++: with <code>`='<\/code>; and with parentheses.<\/p>\n<p><textarea name=\"code\" class=\"cpp:nocontrols:nogutter\" cols=\"60\" rows=\"10\">int x = 3;\nint y(3);<\/textarea>\n<\/p>\n<p>Some C++ programmers prefer to use copyconstructor-style initialisation syntax for clarity because it is the copy constructor that&#039;s invoked in both cases, <em>not<\/em> the assignment operator as one might expect from the use of the equals sign.<\/p>\n<p>But I think clarity is the complete opposite of what you get. It can cause problems where you do not expect them, leading to complicated diagnostics:<\/p>\n<p><textarea name=\"code\" class=\"cpp:nocontrols:nogutter\" cols=\"60\" rows=\"10\">int main() {\nint x(int());\nstd::cout << x;\n}<\/p>\n<p>\/\/ error: undefined reference to 'x(int (*)())'<\/textarea>\n<\/p>\n<p>Although the linker error makes sense if you know that you have declared a function and never defined it, the diagnostic does not really help you fix the problem if you did not see this coming and expected <code>x<\/code> to be equal to 0.<\/p>\n<p><em>&#034;Wait, what. I&#039;ve declared a function?&#034;<\/em><\/p>\n<p>Yep! The only difference between a function declaration <code>int(T)<\/code> and a temporary construction <code>int(x)<\/code> is that <code>T<\/code> is a type whereas <code>x<\/code> is an expression. So:<\/p>\n<p><textarea name=\"code\" class=\"cpp:nocontrols:nogutter\" cols=\"60\" rows=\"10\">\n\/\/ initialises a to value of temporary int 0\nint a = int();<\/p>\n<p>\/\/ initialises b to value of temporary int 3\nint b = int(3);<\/p>\n<p>\/\/ initialises c to value of temporary int 3\nint c(int(3));<\/p>\n<p>\/\/ fail: declares a function d taking a {function\n\/\/ taking a T and returning int} and returning int\nint d(int(T));<\/p>\n<p>\/\/ fail: declares a function e taking a {nullary\n\/\/ function returning int} and returning int\nint e(int());<\/textarea>\n<\/p>\n<p>In the last case above, because the <code>int()<\/code> has nothing inside the parentheses it can be parsed as either, and function declaration is always assumed in C++ where it&#039;s possible.<\/p>\n<p>There are plenty of cases where a type simply cannot be in a situation like this, and in the other cases you can hack around it by forcing the declaration to become an expression with extra parentheses:<\/p>\n<p><textarea name=\"code\" class=\"cpp:nocontrols:nogutter\" cols=\"60\" rows=\"10\">int x((int()));<\/textarea>\n<\/p>\n<p>Still, even if just because of this, I avoid &#034;<code>int x(3);<\/code>&#034; and instead prefer good-old equals-syntax which, although it doesn&#039;t actually invoke the assignment operator, at least does what it says it does: it declares and initialises an integer variable called <code>x<\/code>, equal to 3:<\/p>\n<p><textarea name=\"code\" class=\"cpp:nocontrols:nogutter\" cols=\"60\" rows=\"10\">int x = 3;<\/textarea>\n<\/p>\n<p>Stick to this syntax and you won&#039;t have any trouble; problem solved. \ud83d\ude42<\/p>\n<p><b>Further reading<\/b><\/p>\n<ul>\n<li><a href=\"http:\/\/www.parashift.com\/c++-faq-lite\/ctors.html#faq-10.19\">[10] Constructors Updated! , C++ FAQ Lite<\/a><\/li>\n<li><a href=\"http:\/\/yosefk.com\/c++fqa\/ctors.html#fqa-10.19\">C++ FQA Lite: Constructors<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I compare several approaches to object initialisation in C++.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[21,20],"_links":{"self":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts\/469"}],"collection":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/comments?post=469"}],"version-history":[{"count":3,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts\/469\/revisions"}],"predecessor-version":[{"id":726,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts\/469\/revisions\/726"}],"wp:attachment":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/media?parent=469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/categories?post=469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/tags?post=469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}