{"id":34,"date":"2006-07-01T21:12:37","date_gmt":"2006-07-02T01:12:37","guid":{"rendered":"http:\/\/www.jrtwine.com\/blog\/?page_id=34"},"modified":"2024-05-06T18:09:57","modified_gmt":"2024-05-06T14:09:57","slug":"the-dangers-of-hidden-complexity","status":"publish","type":"page","link":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/","title":{"rendered":"The Dangers of Hidden Complexity"},"content":{"rendered":"<p>One of the things that I think is very dangerous in today&#8217;s software development world in hidden complexity. \u00a0 Hidden complexity is best demonstrated by something that all MFC developers are familiar with &#8211; <code>CString<\/code>. \u00a0 And I present a simple scenario to help with the demonstration.<\/p>\n<p>Imagine that you are interviewing someone for a senior developer position at your company. \u00a0 You have been handed a standard Q&amp;A list from HR which includes some code-related questions that requires typed answers. \u00a0 \u00a0Question #3 seems simple enough: \u00a0 <strong><em>How would you format a random int value for display in a Win32 message box?<\/em><\/strong> \u00a0Each question has a 15 minute time limit for the answer, so after presenting this question to the developer, you decide to go and get some coffee.<\/p>\n<p>When you return 10 minutes later you are surprised to see that the developer is still coding his answer! \u00a0 They complete a couple of minutes later and present you with the following code:<\/p>\n<pre>void \u00a0 \u00a0 \u00a0  Exam1( void )\r\n{ \u00a0 \u00a0  \r\n    long    lTheValue = rand();\r\n \u00a0 \u00a0int \u00a0 \u00a0 iCount = 0;\r\n\r\n \u00a0 \u00a0if( !( rand() % 3 ) ) \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \r\n \u00a0 \u00a0{ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0   \u00a0 \u00a0     lTheValue = -lTheValue;\r\n  \u00a0 }\r\n  \u00a0 unsigned long \u00a0 lValue = 0; \u00a0 \u00a0 \u00a0 \u00a0  \r\n \u00a0  int \u00a0 \u00a0\u00a0 \u00a0 \u00a0 \u00a0 \u00a0iDigitVal = 0;\r\n\r\n  \u00a0 if( lTheValue &lt; 0 ) \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\r\n\u00a0 \u00a0 {\r\n        ++iCount;\r\n        lValue = (unsigned long)(-(long)lTheValue);\r\n    }\r\n    else\r\n    {\r\n        lValue = lTheValue;\r\n    }\r\n    do\r\n    { \r\n        iDigitVal = ( lValue % 10 ); \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 lValue \/= 10; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ++iCount; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 } while( lValue &gt; 0 );\r\n\r\n    char \u00a0 \u00a0*cpBuf = new TCHAR[ iCount + 1 ];\r\n \u00a0  char \u00a0 \u00a0*cpCursor = cpBuf;\r\n \u00a0 \u00a0char \u00a0 \u00a0*cpFirstDigit = NULL;\r\n\r\n \u00a0  if( lTheValue &lt; 0 )\r\n  \u00a0 {\r\n \u00a0 \u00a0 \u00a0  *cpCursor++ = '-';\r\n \u00a0 \u00a0 \u00a0  lValue = (unsigned long)(-(long)lTheValue);\r\n \u00a0  }\r\n    else\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\r\n \u00a0  {\r\n \u00a0 \u00a0    lValue = lTheValue;\r\n\u00a0 \u00a0 }\r\n\u00a0 \u00a0 cpFirstDigit = cpCursor;\r\n  \u00a0 do\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0 \u00a0 \u00a0iDigitVal = ( lValue % 10 ); \r\n        lValue \/= 10;\r\n  \u00a0     *cpCursor++ = char( iDigitVal + '0' );\r\n    } while( lValue &gt; 0 );\r\n\r\n    *cpCursor-- = _T( '\\0' );\r\n    do\r\n    {\r\n        char cSwap = 0;\r\n\r\n        cSwap = *cpCursor;\r\n \u00a0 \u00a0 \u00a0 \u00a0*cpCursor-- = *cpFirstDigit;\r\n        *cpFirstDigit++ = cSwap;\r\n    } while( cpFirstDigit &lt; cpCursor );\u00a0 \u00a0 \u00a0\r\n    \r\n    ::MessageBox( NULL, cpBuf, _T( \"The Value Is\" ),\r\n            MB_OK );\r\n    \r\n    delete [] cpBuf;\r\n \r\n \u00a0  return;\r\n}\r\n<\/pre>\n<p>So you take a good look at the code and see that it is performing a few distinct steps:<\/p>\n<ol>\n<li>It is processing the integer value one time to determine how \u00a0much space will be required to store the int-converted-to-string value<\/li>\n<li>It is dynamically allocating the memory required for the string value based on the calculation above<\/li>\n<li>It processes the integer value a second time to actually generate the int-converted-to-string value and builds it in the allocated buffer<\/li>\n<li>It shows the value in a Win32 MessageBox<\/li>\n<li>It deallocates the memory it allocated earlier<\/li>\n<\/ol>\n<p>Now, step back from the interview scenario and think about the code as it relates to the problem. \u00a0 True, it does exactly what it is supposed to do, but does it not seem a tad bit heavyweight for such a simple problem?<\/p>\n<p>Most developers would look at that solution and figure that there must be a simpler way to do things, and they are 100% correct. \u00a0 However, the problem is this &#8211; suppose the developer, instead of writing the code above, wrote this instead:<\/p>\n<pre>void \u00a0 \u00a0 \u00a0 Exam1( void )\r\n{\r\n    CString sValue;\r\n    int \u00a0 \u00a0 iValue = rand();\r\n\r\n    sValue.Format( _T( \"%d\" ), \u00a0iValue );\r\n    ::MessageBox( NULL, sValue, _T( \"The Value Is\" ),\r\n            MB_OK );\r\n}<\/pre>\n<p>Here is the problem with this code&#8230; \u00a0 Some inexperienced developers (even ones that do not realize that they are inexperienced) would think that this code is much simpler than the original code above, and might even consider it to be an acceptable answer. \u00a0 And, truth be told, it sure looks like a much simpler solution.<\/p>\n<p>But would you believe that the code executed for this usage of <code>CString::Format(...)<\/code> is actually <strong>more complex<\/strong> than the original code above? \u00a0 If the \u00a0<code>CString<\/code> object was not a new object, and had already been used, it might be even more complex if reallocation was necessary. \u00a0 Now what do you think about this code? \u00a0 Not really as simple as it looks, is it?<\/p>\n<p>Why would people accept the above <code>CString<\/code> example as a better solution? \u00a0 Such is the danger with hidden complexity &#8211; there is lots of innocent looking code out there that looks &#8220;simple&#8221; to the inexperienced\/untrained eye. \u00a0 And there are lots of inexperienced\/untrained eyes out there.<\/p>\n<p>As modern, professional developers, we have to start paying attention to the stuff going on behind the scenes. \u00a0 We have to realize that just because something looks simple, does not mean that it is. \u00a0 Knowing what your code is actually doing is important to understanding how to implement a solution.<\/p>\n<p>When the hidden details involve dynamically allocated resources, things get really important. \u00a0 With today&#8217;s modern desktop CPUs offering things like true multi-core ability (Athlon X2, Pentium D, etc.), proper multi-threaded development becomes very important. \u00a0 However, most standard runtime heap implementations use a shared heap. \u00a0 When doing multi-threaded development, the word shared \u00a0normally implies contention.<\/p>\n<p>If you do not know exactly what your code is doing behind the scenes, you cannot identify potential trouble spots where contention may be a concern. \u00a0 Oh, and BTW &#8211; since these <code>CString<\/code> functions can allocate memory, it means that each time they are called is another possible exception point. \u00a0 Do you ever see developers wrapping each call to <code>CString::Format(...)<\/code> with an <code>try<\/code>\/<code>catch<\/code> block?<\/p>\n<p>This kind of ignorance is not something that should be encouraged nor tolerated in the field of software development. \u00a0 With the two top complaints about software generally being about speed\/performance and stability, developers cannot continue to be ignorant of what goes on behind the scenes. \u00a0 This is true for hand-written complied applications just as it is for managed\/interpreted ones built on a framework.<\/p>\n<p>N.B: We are making some strides here &#8211; the new ATL-based <code>CString<\/code> class seems to have a way to customize the allocators used. \u00a0 This is a very nice feature, but I bet it will be under-utilized. \u00a0 For example, Win32 developers have always been able to create pre-thread heaps to help avoid thread contention, but very few actually make use of them. \u00a0 The STL allocators can also be \u00a0customized in a similar way, but this is rarely done. \u00a0 As such, noone should expect these developers to suddenly wake-up and start using per-thread heaps just because <code>CString<\/code> supports it. \u00a0 Developers have to rise to the task by gaining a more detailed\/deep understanding, and using that knowledge to build better solutions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the things that I think is very dangerous in today&#8217;s software development world in hidden complexity. \u00a0 Hidden complexity is best demonstrated by something that all MFC developers are familiar with &#8211; CString. \u00a0 And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-34","page","type-page","status-publish","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"One of the things that I think is very dangerous in today&#039;s software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"James R Twine Blog -\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"The Dangers of Hidden Complexity - James R Twine Blog\" \/>\n\t\t<meta property=\"og:description\" content=\"One of the things that I think is very dangerous in today&#039;s software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2006-07-02T01:12:37+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2024-05-06T14:09:57+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"The Dangers of Hidden Complexity - James R Twine Blog\" \/>\n\t\t<meta name=\"twitter:description\" content=\"One of the things that I think is very dangerous in today&#039;s software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/the-dangers-of-hidden-complexity\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/jrtwine.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/the-dangers-of-hidden-complexity\\\/#listItem\",\"name\":\"The Dangers of Hidden Complexity\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/the-dangers-of-hidden-complexity\\\/#listItem\",\"position\":2,\"name\":\"The Dangers of Hidden Complexity\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog#listItem\",\"name\":\"Home\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/#organization\",\"name\":\"James R Twine Blog\",\"url\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/the-dangers-of-hidden-complexity\\\/#webpage\",\"url\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/the-dangers-of-hidden-complexity\\\/\",\"name\":\"The Dangers of Hidden Complexity - James R Twine Blog\",\"description\":\"One of the things that I think is very dangerous in today's software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/the-dangers-of-hidden-complexity\\\/#breadcrumblist\"},\"datePublished\":\"2006-07-01T21:12:37+00:00\",\"dateModified\":\"2024-05-06T18:09:57+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/\",\"name\":\"James R Twine Blog\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/jrtwine.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"The Dangers of Hidden Complexity - James R Twine Blog","description":"One of the things that I think is very dangerous in today's software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a","canonical_url":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/jrtwine.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/jrtwine.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/#listItem","name":"The Dangers of Hidden Complexity"}},{"@type":"ListItem","@id":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/#listItem","position":2,"name":"The Dangers of Hidden Complexity","previousItem":{"@type":"ListItem","@id":"https:\/\/jrtwine.com\/blog#listItem","name":"Home"}}]},{"@type":"Organization","@id":"https:\/\/jrtwine.com\/blog\/#organization","name":"James R Twine Blog","url":"https:\/\/jrtwine.com\/blog\/"},{"@type":"WebPage","@id":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/#webpage","url":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/","name":"The Dangers of Hidden Complexity - James R Twine Blog","description":"One of the things that I think is very dangerous in today's software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/jrtwine.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/#breadcrumblist"},"datePublished":"2006-07-01T21:12:37+00:00","dateModified":"2024-05-06T18:09:57+00:00"},{"@type":"WebSite","@id":"https:\/\/jrtwine.com\/blog\/#website","url":"https:\/\/jrtwine.com\/blog\/","name":"James R Twine Blog","inLanguage":"en-US","publisher":{"@id":"https:\/\/jrtwine.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"James R Twine Blog -","og:type":"article","og:title":"The Dangers of Hidden Complexity - James R Twine Blog","og:description":"One of the things that I think is very dangerous in today's software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a","og:url":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/","article:published_time":"2006-07-02T01:12:37+00:00","article:modified_time":"2024-05-06T14:09:57+00:00","twitter:card":"summary_large_image","twitter:title":"The Dangers of Hidden Complexity - James R Twine Blog","twitter:description":"One of the things that I think is very dangerous in today's software development world in hidden complexity. Hidden complexity is best demonstrated by something that all MFC developers are familiar with - CString. And I present a simple scenario to help with the demonstration. Imagine that you are interviewing someone for a"},"aioseo_meta_data":{"post_id":"34","title":null,"description":null,"keywords":null,"keyphrases":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_image_url":null,"twitter_title":null,"twitter_description":null,"schema_type":"default","schema_type_options":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null,"created":"2026-09-17 06:40:51","updated":"2026-09-17 06:40:51"},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/jrtwine.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tThe Dangers of Hidden Complexity\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/jrtwine.com\/blog"},{"label":"The Dangers of Hidden Complexity","link":"https:\/\/jrtwine.com\/blog\/the-dangers-of-hidden-complexity\/"}],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/pages\/34","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":5,"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/pages\/34\/revisions"}],"predecessor-version":[{"id":719,"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/pages\/34\/revisions\/719"}],"wp:attachment":[{"href":"https:\/\/jrtwine.com\/blog\/wp-json\/wp\/v2\/media?parent=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}