{"id":18456,"date":"2013-01-21T13:26:34","date_gmt":"2013-01-21T18:26:34","guid":{"rendered":"http:\/\/www.shamusyoung.com\/twentysidedtale\/?p=18456"},"modified":"2013-01-21T13:46:38","modified_gmt":"2013-01-21T18:46:38","slug":"coding-style-part-3","status":"publish","type":"post","link":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=18456","title":{"rendered":"Coding Style Part 3"},"content":{"rendered":"<p><table   class=\"\" cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/splash_frustrated.jpg' class='insetimage'   alt='splash_frustrated.jpg' title='splash_frustrated.jpg'\/><\/td><\/tr><\/table><\/p>\n<p>And so we continue discussing the <a href=\"ftp:\/\/ftp.idsoftware.com\/idstuff\/doom3\/source\/CodeStyleConventions.doc\" title=\"Line to office document on id Software FTP site\">Office document<\/a> that describes the internal coding conventions of id Software. Why? Because I hate having readers and I&#8217;m trying to bore you into going away. So far this plan has backfired spectacularly. You people are just as strange as I am. Let us revel in it. <\/p>\n<p>As before, the style guide is in bold, and everything else is me blathering.<\/p>\n<p><!--more--><strong>Use precision specification for floating point values unless there is an explicit need for a double.<\/strong><\/p>\n<pre lang=\"c\" line=\"1\">\r\n\/\/use\r\nfloat f = 0.5f;\r\n\r\n\/\/Instead of\r\n\r\nfloat f = 0.5;\r\n<\/pre>\n<p>Computers are finite in their ability to manage precision. You can&#8217;t just give a program a a number like (say) 10<sup>50<\/sup>+5. (A one with 49 zeroes after it, then a five.) There are limits to how large your numbers can get or how tiny your decimals can be.  And if you&#8217;re trying to store large numbers and keep track of really fine decimals, then you may find yourself running into these limits quickly. Of course, you can always use more memory to store numbers, but these, uh&#8230; take more memory. Also, it&#8217;s much slower to perform arithmetic on more precise numbers. <\/p>\n<p>In C \/ C++, we have two built in types: <tt>float<\/tt> and <tt>double<\/tt>.  A float has (I think) something like seven digits of significance. (<a href=\"http:\/\/en.wikipedia.org\/wiki\/IEEE_754-2008\" title=\"IEEE Standard for Floating-Point Arithmetic (IEEE 754)\">It&#8217;s complicated<\/a>, but you probably guessed that already.) A double uses twice as much memory, but can store larger and more precise numbers.  If you need astronomically large or precise numbers beyond what double can give you, then you probably have a task that&#8217;s better suited to some other language. <\/p>\n<p>When you specify a number like &#8220;10.2&#8221;, that&#8217;s called a literal. When you type a literal, you have to tell the compiler if you&#8217;re giving it a float or double value. If you stick an f on the end, it&#8217;s a float. If not, it&#8217;ll be treated as a double. <\/p>\n<p>So the rule above means basically, &#8220;put f on the end of all your literal floats&#8221;.  The thing is, every compiler I&#8217;ve ever used will give you a warning if you&#8217;re not rigorous about keeping your floats and doubles straight. This code:<\/p>\n<pre lang=\"c\" line=\"1\">\r\nfloat number = 10.0;\r\n<\/pre>\n<p>&#8230;should ALWAYS trigger a warning.  The compiler will feel the need to remind you, &#8220;Hey man, I&#8217;m just assuming that the 10.0 is a double value.  You know, since you didn&#8217;t put an f on the end. But see, if it&#8217;s a double, then storing it in a float might lose some of the precision. Well, not in this case. But in some other case it might and that seems bad. Anyway, I&#8217;m just letting you know. You don&#8217;t have to change it. But I&#8217;ll bring this up every time you compile if you don&#8217;t.&#8221;<\/p>\n<p>(Note that your compiler might give slightly different messages if you don&#8217;t use the -passiveagressive switch.) <\/p>\n<p>This particular rule is odd because it&#8217;s not just about personal style, readability, or aesthetics.  This particular rule needs to be followed if you don&#8217;t want a bunch of annoying warning flags every time you compile.  This one is so important I&#8217;m surprised it was listed at all.<\/p>\n<p><b>Function names start with an upper case, and in multi-word function names each word starts with an upper case:<\/b><\/p>\n<pre lang=\"c\">\r\nvoid ThisFunctionDoesSomething( void );\r\n<\/pre>\n<p>This has been the most popular style for a long, long time.  Although, at my former day job our internal style was a bit of a renegade in that we still used lowercase mixed with underscores. So the above function would be called this_function_does_something (). Outlandish!<\/p>\n<p>I don&#8217;t really use lowercase function names in my own work. Well, sort of. Okay, see&#8230;<\/p>\n<div class=\"dmnotes\">Programmer talk:<\/p>\n<p>In the past, I&#8217;ve worked on projects where it was considered very important to differentiate between module functions and local functions. If I&#8217;m working in Render.cpp, then all of the functions declared in Render.h would follow the format of Render_____ ().  If the function is NOT in the header file, then it was to be lowercase &#038; underscore style, and declared as static. So&#8230;<\/p>\n<pre lang=\"c\">\r\nstatic void draw_hud ()\r\n{\r\n}\r\n\r\nvoid RenderScene ()\r\n{\r\n}\r\n<\/pre>\n<p>&#8230;are fine, but&#8230;<\/p>\n<pre lang=\"c\">\r\n\/\/This doesn't appear in the header file, and thus shouldn't begin with \"render\".\r\nvoid render_hud ()\r\n{\r\n}\r\n\r\n\/\/This is in the header file, but the name is illegal \r\n\/\/because it should be \"RenderSpeed\", Not Rendering.\r\nvoid RenderingSpeed ()\r\n{\r\n\r\n}\r\n<\/pre>\n<p>&#8230;would both earn you either a grumpy email or a polite admonishment, depending on who found it. <\/p>\n<p>The thing is: I still use this system today, and it wasn&#8217;t until I sat down to write this that I began to question why.  I mean, I follow it because it&#8217;s familiar, but why was this rule made in the first place?  I suppose declaring it as static lets you make new functions without worrying about name collisions. And I can see the value in clearly distinguishing between externally available functions and local ones.  But this doesn&#8217;t seem to come up in other style guides and I wonder if this style was borrowed from elsewhere.\n<\/p><\/div>\n<p>Anyway, it&#8217;s generally a good idea to capitalize your function names. The compiler doesn&#8217;t care, but using lowercase names is just really anachronistic and makes people think you&#8217;re a wrinkly old greybeard. <\/p>\n<p><strong>The standard header for functions is:<\/strong><\/p>\n<pre lang=\"c\">\r\n\/*\r\n====================\r\nFunctionName\r\n\r\n  Description\r\n====================\r\n*\/\r\n<\/pre>\n<p>Gah! Why do you squander <strong>two precious lines<\/strong> of vertical space this way!?! Repent unbeliever!<\/p>\n<p>I kid.  <\/p>\n<p>The thing we&#8217;re looking at here is a comment. In C, a slash followed by an asterisk \/* begins a comment. Everything after that is ignored until an asterisk followed by a slash, like so: *\/  Between those two bookends you can put any dang thing you like. Draw diagrams in ascii art, type profane curses to third-party developers, snark at your fellow coders, or whatever else needed to explain why the following code works the way it does.<\/p>\n<p>in my own projects, I use:<\/p>\n<pre lang=\"c\">\r\n\/*====================\r\n  Description\r\n====================*\/\r\n<\/pre>\n<p>So now we come to the thorny topic of comments. <\/p>\n<p>The point of these headers is so that another coder can see the breaks between sections of code quickly as they scroll down, looking for whatever the problem of the day is. In any reasonable work environment the comments will be shown in a different color. If you make them reach across the screen, then they can do double duty:  They serve as stark visual breaks, and if you stop to read them you can see a synopsis of what this code is for. <\/p>\n<p>I&#8217;m noticing that there&#8217;s this trend among the younger set to eschew comments, perhaps even going so far as to suggest that using comments is indicative of some sort of design flaw. While I usually only complain about style in a half-joking, I-know-this-doesn&#8217;t-really-matter kind of way, this one is really important and I would encourage you to try to view your code through the eyes of a newcomer.  Is it obvious what&#8217;s going on? No? ADD COMMENTS.<\/p>\n<p>I&#8217;m moving away from generic example code for this.  The following is a real block of code that&#8217;s used to calculate surface normals on a mesh with seams. Say you&#8217;ve got a sphere. It&#8217;s actually two hemispheres put together. You want the lighting to shade smoothly over the surface, even where the two halves join.  <\/p>\n<p><table   class=\"\" cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/codingstyle2.jpg' class='insetimage'   alt='codingstyle2.jpg' title='codingstyle2.jpg'\/><\/td><\/tr><\/table><\/p>\n<p>Here is an excerpt of the function to do this. It&#8217;s long. Sorry, but it&#8217;s part of the point I&#8217;m making.  Also note that double slashes are used for single-line comments. This is different from above, where you can make block comments using \/* and *\/ as bookends.<\/p>\n<pre lang=\"c\" line=\"1\">\r\n  \/\/For each triangle...\r\n  for (i = 0; i < Triangles (); i++) {\r\n    index = i * 3;\r\n    i0 = merge_index[_index[index]];\r\n    i1 = merge_index[_index[index + 1]];\r\n    i2 = merge_index[_index[index + 2]];\r\n    \/\/ Convert the 3 edges of the polygon into vectors\r\n    edge[0] = verts_merged[i0] - verts_merged[i1];\r\n    edge[1] = verts_merged[i1] - verts_merged[i2];\r\n    edge[2] = verts_merged[i2] - verts_merged[i0];\r\n    \/\/ normalize the vectors\r\n    edge[0].normalize ();\r\n    edge[1].normalize ();\r\n    edge[2].normalize ();\r\n    \/\/ now get the normal from the cross product of any two of the edge vectors\r\n    normal = GLcross (edge[2], edge[0] * -1);\r\n    normal.normalize ();\r\n    \/\/calculate the 3 internal angles of this triangle.\r\n    dot = GLdot (edge[2], edge[0]);\r\n    angle[0] = acos(-dot);\r\n    if (isnan (angle[0]))\r\n      continue;\r\n    angle[1] = acos(-GLdot (edge[0], edge[1]));\r\n    if (isnan (angle[1]))\r\n      continue;\r\n    angle[2] = (float)PI - (angle[0] + angle[1]);\r\n    \/\/Now weight each normal by the size of the angle so that the triangle\r\n    \/\/with the largest angle at that vertex has the most influence over the\r\n    \/\/direction of the normal.\r\n    normals_merged[i0] += normal * angle[0];\r\n    normals_merged[i1] += normal * angle[1];\r\n    normals_merged[i2] += normal * angle[2];\r\n  }\r\n  \/\/Re-normalize. Done.\r\n  for (i = 0; i < _normal.size (); i++) {\r\n    _normal[i] = normals_merged[merge_index[i]];\r\n    \/\/_normal[i].z *= NORMAL_SCALING;\r\n    _normal[i].normalize ();\r\n  }\r\n<\/pre>\n<p>We actually have a really good example of dumb, useless comments here. Line 11 is a hilariously pointless comment, and the worst thing about it is that I'm pretty sure it's mine. (The one on line 1 is pretty dumb too, although that one should be expanded & clarified rather than removed.)<\/p>\n<p>But the rest of these comments are crucial.  Without those, this would be a wall of math.  Sure, someone who already knows how to create curface normals will be able to follow the steps, but for anyone else this will be an exercise in reverse-engineering. That takes time.<\/p>\n<p>The \"comments are a design flaw\" school of thought suggests that if you feel the need to add a comment, you should instead lift out the code and make it into a function with a descriptive name. But here that would mean adding several new functions and passing a lot of variables around. Each new function would need to be given the original list of vertexes, the new condensed list, the list of triangles, and the normals it's building. That's a lot of crap to pass around, and a lot of times to jump in and out of functions. For a large model, this could introduce a very real and perceptible performance hit. <\/p>\n<p>This would add many lines of code and someone trying to read this thing would need to jump around the source to follow the flow.  I'm not sure how you could turn the comment on line 27-29 into a descriptive name without throwing away a lot of information. It will probably be called <tt>WeightNormalsByAngle ()<\/tt> or somesuch.  <\/p>\n<p>Later, the Other Programmer will be digging through the source, looking for some problem related to specular highlights not working right. They will find <tt>WeightNormalsByAngle ()<\/tt> in the source file and mistake it for something related. \"Is this what I'm looking for? What is this? What calls it? I guess I'd better do a search, see where this is called, and then figure out what it does.\" <\/p>\n<p>So now you've got a larger more confusing source file and you've removed some crucial information. But hey: You saved someone having to scroll past three whole lines of comments! You big, damn hero, you.<\/p>\n<p>In a broader sense, we've got two philosophies:<\/p>\n<ol>\n<li>Write code in such a way that it can't possibly be misunderstood.\n<li>Assume misunderstandings are inevitable and work to mitigate them.\n<\/ol>\n<p>I'm much more inclined to favor the system that allows for mistakes than the system that encourages and requires perfection. <\/p>\n<p>The drawback here is that coders are stereotypically rubbish at writing comments. If you tell them to write comments, you'll get a lot of crud like my comment in line #11 above: needless screen-consuming little post-it notes that obscure the crucial by announcing the obvious.  Still, if a coder is bad at writing comments, I imagine they will be even worse at self-documenting variables and function names. Brevity is the soul of wit.  If you can't say it in five lines then you'll never fit it into twenty characters.<\/p>\n<p>I realize this is probably less of an issue if you're doing things that are self-explanatory. But sooner or later you're going to do something tricky or cryptic.  I don't care what you name your variables or how you lay out your function names, if you don't leave a note for the Other Programmer then you are sowing ruin. The cost of deciphering something tricky is only slightly less than the cost of writing it in the first place. The comments in the above function have saved me a ton of time over the years.  <\/p>\n<p>If you'll indulge me in a little <a href=\"http:\/\/en.wikipedia.org\/wiki\/Argument_from_authority\" title=\"Argument from authority\">argumentum ad verecundiam<\/a>, I'll point out that John Carmack, the lead programmer at id Software, one of the giants of the industry, certified genius, software inventor, and author of the guide we're discussing, is apparently generous with his comments. I haven't looked at the Doom 3 source myself, but it's rumored that almost a third of the lines are comments. If a guy that smart needs comments, how much more will us mere mortals need them?<\/p>\n<p>Seriously. Don't listen to the haters. Comment your freaking source.<\/p>\n<p>To be continued...<\/p>\n","protected":false},"excerpt":{"rendered":"<p>And so we continue discussing the Office document that describes the internal coding conventions of id Software. Why? Because I hate having readers and I&#8217;m trying to bore you into going away. So far this plan has backfired spectacularly. You people are just as strange as I am. Let us revel in it. As before, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66],"tags":[],"class_list":["post-18456","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/18456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=18456"}],"version-history":[{"count":0,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/18456\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=18456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=18456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=18456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}