<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:s="http://www.techrepublic.com/search" xmlns:dc="http://purl.org/dc/elements/1.1/"  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
    <title><![CDATA[Discussion on The most expensive programming mistake ever? ]]></title>
    <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319]]></link>
    <atom:link rel="hub" type="application/rss+xml" href="http://pubsubhubbub.appspot.com/" />
    <atom:link rel="self" type="application/rss+xml" href="http://www.techrepublic.com/forum/discussions/102-347319/rss" />

    <description><![CDATA[]]></description>
    <language>en-us</language>
    <lastBuildDate>2013-05-23T05:59:33-07:00</lastBuildDate>
             

    <item>
        <title><![CDATA[Thanks for the insight]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3485102]]></link>
        <description><![CDATA[I've only been using C for a short while now.  I've always meant to learn it, so I finally did.  Therefore, I'm probably erring on the pedantic side -- because I really don't have the experience to define the difference between &quot;this could happen&quot; and &quot;it could, but never does in practice.&quot;  My portfolio of tested compilers consists of: GCC on Linux x86-64.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3485102]]></guid>
        <dc:creator><![CDATA[nwallette]]></dc:creator>
        <pubDate>Fri, 19 Aug 2011 11:58:10 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[No mistake]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3485080]]></link>
        <description><![CDATA[There also exist interoperability issues with the address + length format: endianness, word-length, field-alignment, definition of #bits / char to name a few. The NUL-terminated choice seems to have served Ken, Dennis, and Brian well in terms of simplicity. My suspicion is that, had they chosen the address + length format, we would now be reading about the costs generated by the mistake of them choosing THAT format 40+ years ago.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3485080]]></guid>
        <dc:creator><![CDATA[medomoreno]]></dc:creator>
        <pubDate>Fri, 19 Aug 2011 11:03:11 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[@nwallette: Re. structs]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484826]]></link>
        <description><![CDATA[True. Some older compilers put struct fields on even address boundaries, perhaps for more optimal access. Most of the ones I saw, though, allocated memory contiguously. I never saw a compiler put fields in reverse order. Maybe you're talking about big endian vs. little endian, where the bytes are reversed?C has been known as a portable language, but there are all sorts of pitfalls like this. I used to write Unix servers, and the way we kept source code portability was to stick pretty much with POSIX compliance, and use libraries that were designed to be portable between the platforms our customers used. Whenever I'd install our server on a new system, I would spend at least a day surveying the customer's system, reading man (&quot;manual&quot;) pages describing the features of its C compiler, and what libraries were on the system, so I could see what adjustments needed to be made to our make files and source code. The source usually only required minor tweaks. The make file was the bigger adjustment. The big thing in each project was making sure that our third-party libraries worked on the new system. If that worked, we were off and running.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484826]]></guid>
        <dc:creator><![CDATA[Mark Miller]]></dc:creator>
        <pubDate>Thu, 18 Aug 2011 19:47:54 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[Re: Structs]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484773]]></link>
        <description><![CDATA[I liked that too.  Then I read that the memory allocation used by structs is implementation-specific.  So, you can't guarantee that a struct with two 32-bit integers will be ordered as intA, intB.  It might by intB, intA.  Or intA, 32-bit pad, intB, 32-bit pad.  Or anything else the compiler wants to do.I started reading my numeric fields 8 bits at a time, and using bit shifting to turn them into 32-bit ints since architecture, byte order, and compiler can all cause the same code to fail at some future time, when I've long forgotten that I need to remember to consider it.It makes me sad, as it could have so easily been defined by the spec and then those shortcuts would be totally legitimate.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484773]]></guid>
        <dc:creator><![CDATA[nwallette]]></dc:creator>
        <pubDate>Thu, 18 Aug 2011 11:42:07 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[re: &amp;quot;your problem?&amp;quot;]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484758]]></link>
        <description><![CDATA[The lack of bounds checking is part of the problem, and it's related to it being null terminated. The fundamental problem, as pointed out by others, is that C doesn't actually have a true &quot;string&quot; type that functions automatically handle properly (which is part of the null termination decision). It's too easy to slip up and do the wrong thing and just copy content directly.J.Ja]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484758]]></guid>
        <dc:creator><![CDATA[Justin James]]></dc:creator>
        <pubDate>Thu, 18 Aug 2011 11:20:47 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[@nwallette: Decimal calculations frustrated me to no end!]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484424]]></link>
        <description><![CDATA[What scared me to death with C was floating-point calculations. I never felt like I quite got a handle on how they worked. All I ever read about them is they were &quot;estimates.&quot; Oh, that's comforting! When they really got screwed up was when I'd use atof() (or perhaps strtod()) to convert a floating-point value stored as a string into a bona fide double value. I don't know what it was, but the string-to-double conversion  always  screwed up even the simplest of floating-point calculations. My guess is there were some garbage bits left over in the mantissa from the conversion. You could take the simplest of cases, like convert &quot;9.00&quot; to 9.0 (or so I thought) and divide that by 3.0, and end up with some screwy decimal like 3.2395725! This was a  nasty bug, because it was difficult to detect. You could even say, &quot;printf(&quot;%f\n&quot;, convertedValue)&quot; just as a sanity check to see if there was something wrong with the converted value, and you'd get an innocuous output, something like 9.0, just like you expected. Nothing wrong, right? It drove me nuts!We got this nasty bug in production code once that went totally undetected through our own testing, and acceptance testing. When I saw it, I was horrified. We were developing a client-server system. One part of the app. downloaded a record that contained a monetary amount, stored as a string. It turned out every time somebody downloaded this type of record, and then sent it back to the server, the monetary value increased by a penny, or something. I forget. Maybe it was more than that. There was absolutely nothing in our code where we were explicitly increasing the amount. It was happening because of the text-to-double conversions we were doing, and possibly some calculations we were doing with the values. I came up with a fix for it, but I felt like I shouldn't have to do this. I'd multiply the converted value by 100.0 (apparently multiplications of this type didn't cause problems), convert the value to an int, just to make sure I got rid of any &quot;junk bits&quot; left in the mantissa from conversion, then convert the int back to double, and divide by 100.0. I think before this I tried using floor(), and I'd still get screwy results. Doing what I described was the only way I could find to make sure I got a &quot;clean&quot; conversion value. It was nuts!]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484424]]></guid>
        <dc:creator><![CDATA[Mark Miller]]></dc:creator>
        <pubDate>Wed, 17 Aug 2011 13:27:29 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[This turned out to be one of C's strengths in some cases...]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484432]]></link>
        <description><![CDATA[...but you're right. You had to be careful with it.In one of the projects I worked on years ago I learned about this technique I could use in parsing a flat file. If I defined a struct with fields that matched the fixed-width fields in a text file, byte for byte, I could use the following code to automatically put the fields into slots:fread(&amp;structVar, sizeof(structType), 1, fileHandle);We were developing a client-server system, and we used flat files to transmit data back and forth between the client and the server. I forget if the client had the same structs and just serialized them, or if my server code had to use strncpy() and sizeof(), and manually null-terminating the strings, to get the field values out. In any case, it was a very effective technique, and it didn't require a lot of code.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484432]]></guid>
        <dc:creator><![CDATA[Mark Miller]]></dc:creator>
        <pubDate>Wed, 17 Aug 2011 13:01:24 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[I learned on K &amp; R C...]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484399]]></link>
        <description><![CDATA[...if that helps explain my comment. It was the original standard developed by Kernighan &amp; Ritchie before ANSI C came along.I wrote a  blog post on how C is misunderstood a while back. In it I have a section where I talk about some of the stuff you could do in K &amp; R C that you can't do in ANSI C. I used it to explain why C is the way it is today, because I see there is a &quot;reason behind the madness.&quot; Some got the impression that I was a big fan of C, and that I was bashing people who didn't &quot;get it.&quot; That wasn't my intention. I was just saying that there were many who were criticizing the language for the wrong reasons, and that there were different, legitimate reasons to criticize it, from a standpoint of understanding what the creators of C were actually trying to do. I said at the end that I'm glad I'm not using it anymore. Not to say I would never, ever go back to it, but I'm glad there are some better options out there.Re. the changing sizes of typesThat was something I thought about back in the '90s when I was working in C, though it didn't keep me up at night. I remember asking my boss about it. I noticed that already int's had expanded from 16- to 32-bits, and I figured that someday we'd get 64-bit computers, and the bit width for int's would expand still further. I asked how the software we were writing then would work on newer hardware, even if the instruction sets were still compatible. Since we always supplied our customers with complete source code in the projects we wrote for them, he said, &quot;They can just recompile the source code with a newer compiler.&quot; I got the idea, but I was still wary of it.This was a selling point of Java when it came out, that an int would always remain 32-bits, because unlike C and C++, primitive types were not dependent on the hardware architecture.The main thing I worried about (though it still didn't keep me up at night), since everyone was becoming more conscious of the constraints programmed into systems 20-30 years earlier with Y2K coming up, was the time value used in C for getting the current date. It had the same wrap-around limitation that nwallette talked about earlier with integers. I figured out that with the bit width of integers at the time (I forget what the bit width was for the time value at the time. Maybe it was a long), that it wouldn't become an issue until 2034, or something. I remember the president of our small outfit asked us to think about any unresolved issues we might need to focus on in the near future to address Y2K. I mentioned this, and he just laughed it off...]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484399]]></guid>
        <dc:creator><![CDATA[Mark Miller]]></dc:creator>
        <pubDate>Wed, 17 Aug 2011 12:46:10 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[Structure by design, requires]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484276]]></link>
        <description><![CDATA[planning, forethought, experience, ie not cheap and quick]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484276]]></guid>
        <dc:creator><![CDATA[Tony Hopkinson]]></dc:creator>
        <pubDate>Wed, 17 Aug 2011 07:44:52 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[What types are there are strong, but most C makes use of]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484216]]></link>
        <description><![CDATA[the weak implicit casting, or passes in pointers and then casts back. The power behind that can be very useful, but at the point you do it the compiler cannot help you.The way it was desribed to me was a Pascal compiler is a policeman, and a C compiler is an accomplice. Compiled C is powerful because of the minimal set of contraints it imposes, but that means the programmer has to police themself.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484216]]></guid>
        <dc:creator><![CDATA[Tony Hopkinson]]></dc:creator>
        <pubDate>Wed, 17 Aug 2011 05:52:15 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[your problem ?]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484177]]></link>
        <description><![CDATA[J Jayour problem seems to be with the lack bounds checking of the allocated memory object/variable and not actually with NULL terminated strings.If that is the point you are trying to make, then I agree that it is a problem, but it not limited to strings and it makes the title of the article quite misleading.I still would not classify that as the worst problem, I do not see it as big of an issue as SQL injection (for one example)]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484177]]></guid>
        <dc:creator><![CDATA[oz penguin]]></dc:creator>
        <pubDate>Wed, 17 Aug 2011 00:48:47 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[confoo]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484190]]></link>
        <description><![CDATA[the events name seems pretty anim.. and that's driving me away]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484190]]></guid>
        <dc:creator><![CDATA[awans]]></dc:creator>
        <pubDate>Wed, 17 Aug 2011 00:23:11 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[While this is a problem, It can be made into a minor one.]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484173]]></link>
        <description><![CDATA[While this is a problem, It can be made into a minor one. The major problem I have seen is: there is never enough time to design a program, but always enough time to fix it.  One of the best programs that I worked on had DOS for the I/O, think speed, reliability, and no programming needed, assembly where speed was needed and all the rest C.  This uses the right tool in the right place.  The second was a top down design. with almost the entire program being comprised of library routines.  This application was for testing PC I/O boards so there was a lot of repetition.   The top down design made sure that all repetitive tasks were done exactly the same, by making them  a library function.  The code was half the size of the previous version did almost three times as much and was about 2.5 times faster.  I say this, because when a probram is structured by design, there are less mistakes and problems than linear coding, and they are easier to identify and fix.I realize a lot of you will say I do that, but a lot wish their management would allow them to do so.The only good argument for linear coding, came from a friend, who works for a government contractor, because no one but his company has anyone who understands the code that they write!!]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484173]]></guid>
        <dc:creator><![CDATA[redave]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 23:34:13 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[Of course, that's obvious.]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484145]]></link>
        <description><![CDATA[But those sorts of programmers shouldn't be writing code for, say, the Windows operating system. Or the code should be better vetted rather than patched after release. Better to not have the option of null-terminated strings if the major software houses cannot get it right.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484145]]></guid>
        <dc:creator><![CDATA[seanferd]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 20:38:40 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[Interesting take]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484141]]></link>
        <description><![CDATA[I don't know if I agree on the type argument -- though I am looking at it from the perspective of someone who has only ever used ANSI C.  I find it to be very strongly typed.  BUT, there are really only a very small number of actual data types to chose from.There are, however, a lot of &quot;specific&quot; types that are just recycled generic types under the hood.  Char is the perfect example.  You can have a signed char because a char is just an aliased integer.  If it were a unique type, there probably wouldn't be a signed variation.  (And if strings were a type, 0x00 would just be another character.)I honestly don't know how C programmers slept at night before u/intXX_t, size_t, etc., were conceived.  Not knowing whether your numbers rolled over at 16, 32, or 64 bits would send me into neurotic fits.Also, I'm not sure whether pointer arithmetic is a blessing or curse.  I love that you can iterate over arrays, or through memory, by adding to an address.  But one of the reasons I like C is the lack of black magic.  Unfortunately:int *i = &amp;someaddress;i++;... is totally black magic.  How many bytes did you just jump?  I would really have preferred:int *i = &amp;someaddress;i += sizeof(someaddress);... which, of course, does NOT do what you expect, if you're new and don't realize that's exactly what &quot;++&quot; is really doing for you.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484141]]></guid>
        <dc:creator><![CDATA[nwallette]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 18:53:55 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[Correct]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484131]]></link>
        <description><![CDATA[Re. C doesn't have a string typeThis goes back to the original K &amp; R C language. One of the first things I learned about C was it didn't really care about types. C  looked  like a high level language that would care about types, would make sure you passed the correct number of parameters to a function, and would make sure you didn't go beyond the bounds of allocated memory, but it really wasn't. ANSI C implements type safety, and counts parameters (still no bounds checking), but this only came in the early '90s. In K &amp; R, types were mere descriptors for bit length and offsets into memory. I remember wondering what the point of using these descriptors was. They really didn't mean anything. A char was 8 bits, a byte. That was all. An int was 16- bits, a word. And a long was 32-bits (long word). This has all since changed. As the bit-width of processors have increased, the bit-width signified by these descriptors has increased as well. With K &amp; R, if you defined your own type with typedef, or a struct, again, all that meant to it was a descriptor for the size of the blob of memory you needed, and what, if any, offsets it needed to calculate for access into that blob.All a string is in C is an array where each element is &quot;char length,&quot; 8 or 16 bits, depending on how the compiler interprets the descriptor. What adds even more weirdness is you can have signed and unsigned chars. Why? Because really char is like all the other types. It's a little blob of memory that stores a number. It is nothing more than that. Since the data in memory is numeric (which is what all data is in your computer), it can be signed or unsigned, telling whether the value is positive or negative. A negative character? No, a negative 8- or 16-bit  number! This is the thing that probably throws most people off about C. It puts a pretty cover over the internals of your computer, which is what you're really manipulating with it. It does some nice things for you, which an assembly programmer would have to do manually, like allocating memory, calculating offsets into memory, dereferencing an address to get to data, and pushing and popping things off a runtime stack. Plus, it provides some constructs for conditionals and loops, allows you to create &quot;char array literals&quot; (text you surround in double-quotes, for which the compiler allocates memory, and adds a null-terminator), and a couple data structures: structs and unions. Otherwise, you've got the standard library that provides some level of abstraction for I/O, and strings. Other than that, you're up to your neck in the computer's internals, and you're on your own!]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484131]]></guid>
        <dc:creator><![CDATA[Mark Miller]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 17:34:06 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[What about integer overflows?]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484130]]></link>
        <description><![CDATA[I love C.  I really do.  But, I always battle a little internally with whether I should negate any performance benefit I would get by using C, or allow thousands of tiny bugs.Because, face it, any line like this:i++;... is technically a bug.  Instead, the only &quot;safe&quot; way would be:if (i  2^64 bytes.I still can't stand Java, though.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484130]]></guid>
        <dc:creator><![CDATA[nwallette]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 17:04:19 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[Aye well the bit that is being glossed over here is that C]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484101]]></link>
        <description><![CDATA[doesn't have a string type....If it had they would have more options.Choice was pretty much taken out of our hands, but anyone sane who compared the gain of the extra performance of null terminated string versus the huge number of really painful bugs it could, would, did and still causes, would have opted for something with a bit more discipline.I've seen one or two C experts makes this mistake as well, vene the ones who built their own routines and passed length as well, and did their own checking.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484101]]></guid>
        <dc:creator><![CDATA[Tony Hopkinson]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 14:33:42 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[You can pass arrays in Pascal with no literal bounds]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484100]]></link>
        <description><![CDATA[and then get them Low and High, but you can do that because of range checking, but yes you do have to have them if you declare a type.As you say though the real problem was C, you could give yourself the same sort of issues in pascal, you just had to write a fair bit of code to do it. ]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484100]]></guid>
        <dc:creator><![CDATA[Tony Hopkinson]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 14:27:58 -0700</pubDate>
    </item>
             

    <item>
        <title><![CDATA[A mistake in more ways than one]]></title>
        <link><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484074]]></link>
        <description><![CDATA[The &quot;mistake&quot; mentioned is at least understandable in that the security implications could not have been foreseen when C was being developed. However, the comment that &quot;using them without understanding them is [a mistake]&quot; is rather short-sighted on its own.The null-terminated string is a good example of a leaky abstraction. Ideally, the programmer shouldn't know or care about how a string is terminated, only that the end of the string is &quot;somehow&quot; detectable.The best implementation I have seen was how it was done on the VAX. The header was two words. The first word consisted of two short-words: the number of bytes allocated and the number of bytes actually used. The second word was the address of the first character.Using something like this, the current length and the maximum defined length are easily discerned and resizing was also very easy. There would also be no reason for the programmer to know anything about the descriptor or how it worked. Only that it did.]]></description>
        <guid><![CDATA[http://www.techrepublic.com/forum/discussions/102-347319-3484074]]></guid>
        <dc:creator><![CDATA[TommCatt]]></dc:creator>
        <pubDate>Tue, 16 Aug 2011 13:31:03 -0700</pubDate>
    </item>
    </channel>
</rss>

