{"id":25593,"date":"2007-08-14T10:00:00","date_gmt":"2007-08-14T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/08\/14\/what-is-the-order-of-evaluation-in-c\/"},"modified":"2007-08-14T10:00:00","modified_gmt":"2007-08-14T10:00:00","slug":"what-is-the-order-of-evaluation-in-c","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070814-00\/?p=25593","title":{"rendered":"What is the order of evaluation in C#?"},"content":{"rendered":"<p>\nThe C and C++ languages leave the order of evaluation generally\nunspecified aside from specific locations called <i>sequence points<\/i>.\nSide effects of operations performed prior to the sequence point\nare guaranteed visible to operations performed after it.&sup1;\nFor example, the C comma operator introduces a sequence point.\nWhen you write <code>f(),\ng()<\/code>, the language guarantees\nthat any changes to program state made by the function <code>f<\/code>\ncan be seen by the function <code>g<\/code>;\n<code>f<\/code> executes before <code>g<\/code>.\nOn the other hand, the multiplication operator does not introduce\na sequence point.\nIf you write <code>f() * g()<\/code>\nthere is no guarantee which side will be evaluated first.\n<\/p>\n<p>\n(Note that order of evaluation is not the same as associativity and\noperator precedence.\nGiven the expression <code>f() + g() * h()<\/code>,\noperator precedence says that it should be evaluated\nas if it were written <code>f() + (g() * h())<\/code>,\nbut that doesn&#8217;t say what order the three functions will be evaluated.\nIt merely describes how the results of the three functions will be\ncombined.)\n<\/p>\n<p>\nIn the C# language, the order of evaluation is spelled out more\nexplicitly.\n<a HREF=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/Aa691322\">\nThe order of evaluation for operators is left to right<\/a>.\nif you write <code>f() + g()<\/code> in C#,\nthe language guarantees that\n<code>f()<\/code> will be evaluated first.\nThe example in the linked-to page is even clearer.\nThe expression <code>F(i) + G(i++) * H(i)<\/code> is\nevaluated as if it were written like this:\n<\/p>\n<pre>\ntemp1 = F(i);\ntemp2 = i++;\ntemp3 = G(temp2);\ntemp4 = H(i);\nreturn temp1 + temp3 * temp4;\n<\/pre>\n<p>\nThe side effects of each part of the expression take effect in left-to-right\norder.\nEven\n<a HREF=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/Aa691335\">\nthe order of evaluation of function arguments is strictly left-to-right<\/a>.\n<\/p>\n<p>\nNote that\n<a HREF=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/Aa691105\">\nthe compiler has permission to evaluate the operands in\na different order if it can prove that the alternate order of evaluation\nhas the same effect as the original one<\/a>\n(in the absence of asynchronous exceptions).\n<\/p>\n<p>\nWhy does C# take a much more restrictive view of the order of evaluation?\nI don&#8217;t know, but I can guess.&sup2;<\/p>\n<p><p>\nMy guess is that the language designers wanted to reduce the\nfrequency of a category\nof subtle bugs (in this case, order-of-evaluation dependency).\nThere are many other examples of this in the language design.\nConsider:\n<\/p>\n<pre>\nclass A {\n void f()\n {\n  int i = 1;\n  if (true) {\n   int i = 2; \/\/ error - redeclaration\n  }\n }\n int x;\n void g()\n {\n  x = 3; \/\/ error - using variable before declared\n  int x = 2;\n }\n}\n<\/pre>\n<p>\nThe language designers specified that\nthe scope of a local variable in C# extends to the\n<i>entire<\/i> block in which it is declared.\nAs a first consequence of this,\nthe second declaration of <code>i<\/code>\nin the function <code>f()<\/code>\nis illegal since its scope overlaps with the scope of the first\ndeclaration.\nThis removes a class of bugs that can be traced to one local variable\nmasking another with the same name.\n<\/p>\n<p>\nIn the function <code>g()<\/code> the assignment <code>x = 3;<\/code>\nis illegal because the <code>x<\/code> refers not to the member variable\nbut to the local variable declared below it.\nNotice that the scope of the local variable begins with the entire block,\nand <i>not<\/i> with the point of declaration as it would have been in C++.\n<\/p>\n<p>\n<b>Nitpicker&#8217;s Corner<\/b>\n<\/p>\n<p>\n&sup1;This is a simplified definition of <i>sequence point<\/i>.\nFor more precise definitions, consult the relevant standards documents.\n<\/p>\n<p>\n&sup2;I have not historically included the sentence\n&#8220;I don&#8217;t know but I can guess&#8221; because this is a blog,\nnot formal documentation.\nEverything is my opinion, recollection, or interpretation.\nBut it seems that people take what I say to\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2007\/08\/10\/4315707.aspx#4334811\">\nestablish the official Microsoft position on things<\/a>,\nso now I have to go back and add explicit disclaimers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The C and C++ languages leave the order of evaluation generally unspecified aside from specific locations called sequence points. Side effects of operations performed prior to the sequence point are guaranteed visible to operations performed after it.&sup1; For example, the C comma operator introduces a sequence point. When you write f(), g(), the language guarantees [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-25593","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The C and C++ languages leave the order of evaluation generally unspecified aside from specific locations called sequence points. Side effects of operations performed prior to the sequence point are guaranteed visible to operations performed after it.&sup1; For example, the C comma operator introduces a sequence point. When you write f(), g(), the language guarantees [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/25593","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=25593"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/25593\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=25593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=25593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=25593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}