<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx</link><description>In a comment on yesterday's post, Manip asked: Larry: You said Macros work to hide the complexity and say so like it is a bad thing.. ? Excuse me but I thought that was the POINT of using a Macro.. Actually, in the world in which I live (writing systems</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273288</link><pubDate>Wed, 01 Dec 2004 21:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273288</guid><dc:creator>Rick Brewster</dc:creator><description>This is also why choosing &amp;quot;Optimize for Speed&amp;quot; may be less helpful than choosing &amp;quot;Optimize for Size.&amp;quot; Saving 50-100 cycles here and there is helpful, but saving 50-100ms at startup is even better.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273303</link><pubDate>Wed, 01 Dec 2004 21:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273303</guid><dc:creator>Larry Osterman</dc:creator><description>A good point Rick.&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273307</link><pubDate>Wed, 01 Dec 2004 21:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273307</guid><dc:creator>Gene Hamilton</dc:creator><description>Then sometimes you get disgruntled employees that do this with macros: &lt;br&gt;&lt;br&gt;#define printf if((rand() % 2000) == 0) exit(0);</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273328</link><pubDate>Wed, 01 Dec 2004 22:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273328</guid><dc:creator>Peter Newman</dc:creator><description>As I remember reading somewhere, not only does &amp;quot;Optimize for Size&amp;quot; speed up the initial from-disk load, but it also reduces the number of memory pages your code is across, thus reducing the page-in/out delays.&lt;br&gt;&lt;br&gt;It's what I ususally use.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273531</link><pubDate>Thu, 02 Dec 2004 04:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273531</guid><dc:creator>Steve Dispensa</dc:creator><description>Another reason to hate complexity, of course, is that complex code requires complex coders and complex documentation.  Even then, it often hides problems. I remember a bug in an NDIS driver I wrote once that resulted from the fact that the &amp;quot;function&amp;quot; I was calling was really a macro with side effects for which I was unprepared.&lt;br&gt;&lt;br&gt;Complexity is a killer for a dev team &amp;gt;= 2 people.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273578</link><pubDate>Thu, 02 Dec 2004 06:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273578</guid><dc:creator>Manip</dc:creator><description>Larry, thanks for the answer. I see what you mean, I am not going to stop using Macros in my code but I might give them each individually some more thought (as opposed to using a procedure). </description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273653</link><pubDate>Thu, 02 Dec 2004 10:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273653</guid><dc:creator>Daniel Quadros</dc:creator><description>Larry,&lt;br&gt;&lt;br&gt;Sorry but I can&amp;#180;t (completely) agree with you&lt;br&gt;&lt;br&gt;I am an old scholl developer, who started writing  8080 assembly code in the early 80's and moved on to C about the time of DOS 3.&lt;br&gt;&lt;br&gt;There is a clear limit on the complexity of a program you can write with completely in-lining your code. At some point yoy have to structure it, by means of macros, subroutines or (glup!) objects. By doing this, you are hidding complexity.&lt;br&gt;&lt;br&gt;In your DOS 4 BIOS example, the hidding was moved on from the macro to a subrotine and the possibility of something going wrong do to not understanding what is inside it is still there.&lt;br&gt;&lt;br&gt;I've also beem burned a lot of times by code that was &amp;quot;hidden&amp;quot; in a macro, a subrotine, a library or in the OS.&lt;br&gt;&lt;br&gt;The solution? Better documentation (the free software folks will also say access to the source, but I wil trade good docs for source code anytime).&lt;br&gt;&lt;br&gt;And yes, Steve, critical code should be writen by the best coders and get the best documentation. &lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273737</link><pubDate>Thu, 02 Dec 2004 15:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273737</guid><dc:creator>Larry Osterman</dc:creator><description>Daniel,&lt;br&gt;  The complexity I'm talking about is what happens when you see:&lt;br&gt;&lt;br&gt;    ENTER_CRITICAL_SECTION(CritSec);&lt;br&gt;&lt;br&gt;When you look at the source code, you see one line.&lt;br&gt;&lt;br&gt;When you look at the assembly language, you see a kilobyte of code.&lt;br&gt;&lt;br&gt;As code moves from one developer to another, this problem gets worse - the next developer doesn't realize the costs of calling the function, so they blindly use it.&lt;br&gt;&lt;br&gt;This happens with more than just macros.  How much code is added to your application when you add:&lt;br&gt;&lt;br&gt;vector&amp;lt;myType&amp;gt; myVector&lt;br&gt;&lt;br&gt;to your code?&lt;br&gt;&lt;br&gt;When you add:&lt;br&gt;&lt;br&gt;vector&amp;lt;myOtherType&amp;gt; myOtherVector&lt;br&gt;&lt;br&gt;you bring in exactly the same amount of code, just by adding a single line of code in the source.&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273739</link><pubDate>Thu, 02 Dec 2004 15:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273739</guid><dc:creator>Tim Smith</dc:creator><description>You also see this problem with a lot of the new complex compiler constructs and managed data in C++/STL.  Just because it takes one line of code to write, doesn't mean it is fast to run.&lt;br&gt;&lt;br&gt;I once saw a routine that tried to count the number of words in a string (lets ignore the complexity of doing this for something else other than U.S. English).  They used what they were use to using, a managed string such as CString (in this case is was Borland's AnsiString).  The algorithm worked by chopping off the front of the string the whitespace and words until the string became empty.  In other words, for every word in the string, they hit the memory manager four times (two allocations and two frees).  &lt;br&gt;&lt;br&gt;Even though the routine looked simple, it was a memory and CPU hog.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273741</link><pubDate>Thu, 02 Dec 2004 15:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273741</guid><dc:creator>Tim Smith</dc:creator><description>On the bloat of std::vector:&lt;br&gt;&lt;br&gt;I switched from std::vector to a home grown array where I didn't need all the &amp;quot;power&amp;quot;.  For every unique template instance of the vector that was replaced, the application dropped by 3-4k in size.  For a WTL application that was only 200k is size, the savings was huge.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273788</link><pubDate>Thu, 02 Dec 2004 17:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273788</guid><dc:creator>Daniel Quadros</dc:creator><description>My point is that hidding complexity is a must for big projects. Hidding complexity is a Good Thing, and is the base for structured and object oriented programming.&lt;br&gt;&lt;br&gt;The alternative to hidding complexity is to expose it at every step, by not using macros, templates, funcions cals or objects. The resulting program is a nightmare, cause your trying to take everything in acount at the same  time.&lt;br&gt;&lt;br&gt;Of course you will have to do it in Assembly, because the compiler is hiding the complexity of the instruction set and memory allocation ;)&lt;br&gt;&lt;br&gt;I find it very usefull in programming that I studied engineering and have some notion of what happens inside a CPU, but most of the time I am thinking very above this level.&lt;br&gt;&lt;br&gt;Daniel&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273887</link><pubDate>Thu, 02 Dec 2004 19:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273887</guid><dc:creator>mikeb</dc:creator><description>Isn't it really a trade-off (as with many things?).  The macros may have been calls to functions instead of inline code.  In fact, I wouldn't be surprised if the fix for the code size problem was to change the macro definitions to function calls instead of changing each instance of the macro use.&lt;br&gt;&lt;br&gt;Virtually all choices in programming is a tradeoff between complexity, size, and speed.&lt;br&gt;&lt;br&gt;C hides the complexity of assembly.  The CLR hides the complexity of managing memory.  &lt;br&gt;&lt;br&gt;Templates hide the complexity of... actually a lot of the template usage I've seen seem to increase complexity (at least in the implementation of the templated classes).&lt;br&gt;&lt;br&gt;Anyway, one of the key jobs of a developer is to manage these kinds of tradeoffs properly.&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#273888</link><pubDate>Thu, 02 Dec 2004 19:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:273888</guid><dc:creator>Michael Grier [MSFT]</dc:creator><description>The issue is how well you can hide the complexity.&lt;br&gt;&lt;br&gt;For example, CreateFile() works well enough that generally you aren't concerned with the reality behind the scenes.  It's a fairly solid abstraction to work from.&lt;br&gt;&lt;br&gt;My team uses a set of macros for error handling and we did (IMO) a good job on building a solid, non-leaky abstraction.  We pay careful attention to the size and quality of the code generated and the simplicity and directness of the code is easily worth it.&lt;br&gt;&lt;br&gt;Macros vs. functions vs. templates are really no different here - they all hide concepts and complexity.  You always have to be careful about your dependencies and who you use and make sure that you use things in the way that they were intended to be used and that the things you use want to support you.  (They're not our there from the goodness of their heart, they're trying to solve problems and maybe make money so as usual, all engineering decisions are in an economic context, not an academic one.)&lt;br&gt;&lt;br&gt;Re: size/speed:&lt;br&gt;&lt;br&gt;It's funny because the compiler folks think that compiling for size is stupid but we still build almost all of windows for size because (a) the on-disk footprint costs and (b) except for some rare code paths like rendering or the i/o path in servers, we're usually more memory-constrained than CPU-constrained.  It really doesn't matter if the icon will draw in 3% less time if we had to take a page fault to get to the code to draw it.&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#274054</link><pubDate>Fri, 03 Dec 2004 00:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:274054</guid><dc:creator>Foolhardy</dc:creator><description>If you use a template that never touches the template type, but always uses pointers or references to it, the amount of code produced can be reduced considerably; the compiler can use the same code for a pointer, regardless of type, in many cases.&lt;br&gt;&lt;br&gt;Take a linked list: each link needs its data and a pointer to the next link. If you use a pointer for the data instead of storing it directly, the code implementation for manipulating links can be the same. It's still a pointer even if it's a pointer to an int or to a MyClass. The compiler will realize this and merge eqivalnet implementations into a single code output. The type safety of a template without code bloat.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#274058</link><pubDate>Fri, 03 Dec 2004 01:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:274058</guid><dc:creator>Larry Osterman</dc:creator><description>The problem with this Foolhardy is that you lose RAII for those templates - And someone has to allocate and free that memory so you trade heap fragmentation for code size.  I'm not sure which is better.&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#274063</link><pubDate>Fri, 03 Dec 2004 01:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:274063</guid><dc:creator>Norman Diamond</dc:creator><description>I think one of the points here has been that between two ways of hiding complexity, macros vs. function calls, macros are more dangerous.  If a macro is nontrivial then it uses enormous amounts of memory (per occurence) instead of just enormous amounts of time.&lt;br&gt;&lt;br&gt;If a macro calls a function, if the macro only adds a trivial amount of additional wrapping or whatever, then the main cost is in the function, the same as it would be if a macro were not involved.  Then every call still takes the amount of CPU time that the function needs, but the function only occupies its allotment of memory once.&lt;br&gt;&lt;br&gt;As for whether abstractions and complexity hiding are good or bad, well they've been added to every language that was ever invented.  Macros were invented for assembly language before they were invented for C.  Fortran had ordinary subroutines and functions and also had statement functions.  Lisp had function definitions and recursion.  It is impossible to write a nontrivial program without them.&lt;br&gt;&lt;br&gt;Badness comes about when a program calls overly expensive versions when cheaper versions would have sufficed.  The abstraction might be partly to blame, but it's still virtually impossible to live without the abstraction.&lt;br&gt;&lt;br&gt;Badness also comes about even when a program uses cheap operations if it uses orders of magnitude more of them than necessary.  For example someone thinks sorting is expensive so they write their own sort routine without calling any subroutines, and they write an order n-squared sort.  The abstraction is not to blame in these cases.</description></item><item><title>In Principio &amp;raquo; hiding complexity is a very, very bad thing</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#274915</link><pubDate>Sat, 04 Dec 2004 11:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:274915</guid><dc:creator>TrackBack</dc:creator><description>In Principio &amp;amp;raquo; hiding complexity is a very, very bad thing</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#275388</link><pubDate>Mon, 06 Dec 2004 00:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:275388</guid><dc:creator>Norman Diamond</dc:creator><description>By the way, 12/2/2004 11:16 AM Michael Grier [MSFT]&lt;br&gt;&lt;br&gt;&amp;gt; It's funny because the compiler folks think&lt;br&gt;&amp;gt; that compiling for size is stupid&lt;br&gt;&lt;br&gt;30 years ago it actually was, and the problem is that compiler books haven't been updated adequately since then.&lt;br&gt;&lt;br&gt;30 years ago, although there were some machines with virtual memory, they were still in the minority and they weren't the most powerful machines.  It was understandable that speed was more important than size in those days.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#275654</link><pubDate>Mon, 06 Dec 2004 14:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:275654</guid><dc:creator>Larry Osterman</dc:creator><description>Norman,&lt;br&gt; 25 years ago, compiling for size WAS compiling for speed.  The memory on systems was so slow that the fetch time for reading from RAM overrode the time to execute the instructions (for all instructions except DIV and MUL).&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#276046</link><pubDate>Tue, 07 Dec 2004 01:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:276046</guid><dc:creator>Norman Diamond</dc:creator><description>12/6/2004 6:50 AM Larry Osterman &lt;br&gt;&lt;br&gt;&amp;gt; 25 years ago, compiling for size WAS&lt;br&gt;&amp;gt; compiling for speed.&lt;br&gt;&lt;br&gt;Was not.&lt;br&gt;&lt;br&gt;In systems without virtual memory 25 or 30 years ago, compiling for speed meant things like inlining instead of calling functions (in the generated object code), and unrolling loops, and all kinds of things to reduce the number of instructions executed.&lt;br&gt;&lt;br&gt;Compiling for size became important only when hard limits on memory size were being hit.  This did even happen sometimes in embedded systems.  Usually in embedded systems you want to optimize for speed, but if you hit the limit of your address space or the affordable limit on installed RAM or ROM, and if there's no such thing as disk drives or other places to swap out some of your data, then you have to start optimizing for size.  Then you want to choose functions that are comparatively large and called comparatively few times and decide not to inline those, and choose which loops not to unroll, etc.  Or do humongous amounts of work to operate on hash tables and figure out some hashing functions that will avoid using too much memory, instead of simple direct array accesses.&lt;br&gt;&lt;br&gt;There were always tradeoffs between space and time.  Compiling for size was never the same as compiling for speed until virtual memory and page faults took over.</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#276047</link><pubDate>Tue, 07 Dec 2004 01:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:276047</guid><dc:creator>Larry Osterman</dc:creator><description>Norman,&lt;br&gt;  That might be the case on big iron machines, but on PCs, the memory bandwidth far outweighted the processor speed.&lt;br&gt;&lt;br&gt;  Interestingly enough, we've come full circle - these days, memory bandwidth of the system is usually the bottleneck in big systems.&lt;br&gt;&lt;br&gt;</description></item><item><title>re: Hiding Complexity</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#277986</link><pubDate>Wed, 08 Dec 2004 01:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:277986</guid><dc:creator>Norman Diamond</dc:creator><description>Programming embedded systems using Intel's compilers and assemblers, including one of the same processors that some PCs used, compiling for size and compiling for speed were still opposites.  Programming embedded systems using other microprocessors' tools was the same.  The problem was the same as on big iron.  It didn't change until virtual memory and page swapping took over, and then the change affected both PCs and big iron.  Mostly it hasn't affected embedded systems (though the microprocessor's on-chip cache can cause part of the same problem in an even more complicated manner).&lt;br&gt;&lt;br&gt;&amp;gt; these days, memory bandwidth of the system&lt;br&gt;&amp;gt; is usually the bottleneck in big systems. &lt;br&gt;&lt;br&gt;And in PCs, since memory is big enough for it now.  The next release of Windows will take care of that though, won't it?  Will need paging even when we have 8GB of real RAM, right?</description></item><item><title> Larry Osterman s WebLog Hiding Complexity | debt solutions</title><link>http://blogs.msdn.com/larryosterman/archive/2004/12/01/273160.aspx#9756918</link><pubDate>Tue, 16 Jun 2009 03:37:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9756918</guid><dc:creator> Larry Osterman s WebLog Hiding Complexity | debt solutions</dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://debtsolutionsnow.info/story.php?id=10682"&gt;http://debtsolutionsnow.info/story.php?id=10682&lt;/a&gt;&lt;/p&gt;
</description></item></channel></rss>