# Extremeely basic programming question.

**URL:** <https://boards.straightdope.com/t/extremeely-basic-programming-question/624300>\
**Category:** Factual Questions\
**Created:** [June 6, 2012, 6:48pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300 "2012-06-06T18:48:37Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![Chronos](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/chronos/32/134_2.png) [@Chronos](https://boards.straightdope.com/u/Chronos)\
**Post date:** [June 7, 2012, 8:58pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/81 "2012-06-07T20:58:31Z")

</div>

> [@](#):
>
> To cite one of the worst abominations, straight from Kernighan and Ritchie, the following example is given of the complete executable code needed to copy a character string from src to dst:
> 
> while ( \*dst++ = \*src++ ) { }
> 
> This works. But if you think you know why, you’re probably wrong (unless you aren’t). I had to stare at it for a long time to figure out why it works. On the surface, this loop continues to copy bytes as long as they are not zero. Why does it copy up to and including the 0-byte that terminates the string?

Is this something to do with the distinction between putting the ++ after the variable versus before it? Because personally, I deal with that distinction by avoiding it entirely. If I want to increment a variable, then I use a statement that increments the variable and does nothing else. If a compiler wants to optimize that into something else, that’s the compiler’s problem, not mine.

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [June 7, 2012, 9:10pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/82 "2012-06-07T21:10:03Z")

</div>

> [@Chronos](#):
>
> Is this something to do with the distinction between putting the ++ after the variable versus before it? Because personally, I deal with that distinction by avoiding it entirely. If I want to increment a variable, then I use a statement that increments the variable and does nothing else. If a compiler wants to optimize that into something else, that’s the compiler’s problem, not mine.

Not really. It’s a comparison operation that occurs after the copy is done. But you are wise to avoid pre- and post-increments. They are artifacts of the DEC instruction set and can cause confusion. Efficiency is rarely an issue anymore, clarity always is.

---

<div class="post-metadata">

**Author:** ![Indistinguishable](https://avatars.discourse-cdn.com/v4/letter/i/90ced4/32.png) [@Indistinguishable](https://boards.straightdope.com/u/Indistinguishable)\
**Post date:** [June 7, 2012, 9:22pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/83 "2012-06-07T21:22:19Z")

</div>

> [@Senegoid](#):
>
> Heck, all a Real C programmer is doing is writing assembly language in C. To cite one of the worst abominations, straight from Kernighan and Ritchie, the following example is given of the _complete executable code_ needed to copy a character string from src to dst:
> 
> while ( \*dst++ = \*src++ ) { }
> 
> This works. But if you _think_ you know why, you’re probably wrong (unless you aren’t). I had to stare at it for a long time to figure out why it works. On the surface, this loop continues to copy bytes as long as they are not zero. Why does it copy up to _and including_ the 0-byte that terminates the string? Once properly understood, this code is seen to be the worst kind of violation of the very principles of structured programming that were considered so important – all the worse because it _looks_ like such proper structured programming on the surface! (Exercise for the reader: Can you see and explain why it’s a violation of structured programming, and all the worse because it looks so right?)

Much as I dislike having ++ and = return values, it seems straightforward why this code works… the while loop will only terminate after the condition evaluates to false, and the value of the condition is the value of the last byte copied. So the while loop will only terminate after the 0-byte has been copied.

Why is this such a violation of structured programming? Because the condition is “impure” (evaluating it causes a side effect; to wit, a byte to be copied and src and dest to increment)? The moment the while loop was written with an empty body, it should’ve been obvious the condition was intended to be impure.

---

<div class="post-metadata">

**Author:** ![Indistinguishable](https://avatars.discourse-cdn.com/v4/letter/i/90ced4/32.png) [@Indistinguishable](https://boards.straightdope.com/u/Indistinguishable)\
**Post date:** [June 7, 2012, 9:30pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/84 "2012-06-07T21:30:12Z")

</div>

(Perhaps instead of “impure”, I should say “effectful”; truly “pure” conditions (in the sense of being not only side-effect free but also evaluating to the same value every time) are completely useless in loops, either causing the loop body to never run or to run forever)

---

<div class="post-metadata">

**Author:** ![Jragon](https://avatars.discourse-cdn.com/v4/letter/j/e19b73/32.png) [@Jragon](https://boards.straightdope.com/u/Jragon)\
**Post date:** [June 7, 2012, 9:36pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/85 "2012-06-07T21:36:46Z")

</div>

I don’t see what’s so confusing about it, C’s syntax allow for assignments to be done in conditionals, and the leftmost assignment will be used as the value in the conditional (that is, if you assign 0 it acts as false, else true). ETA: Indistinguishable put it better, “=” returns a value equal to the expression on the right hand side.

Aside from that quirk of C, the only other confusing thing is that the post-increment operator binds higher than the dereference operator, so ++ increments the pointer instead of the character. I guess the only other thing to note is that the post-increment operator doesn’t affect the quirk I mentioned in the first paragraph (that is int i = 0; while (i++) { } is a while loop that will never execute any code), because post-increment tells it to evaluate after the while loop does.

All you’re really doing is a very annoying to read version of

```auto

char x = 1;
while ( x ){
  *dest = *src;
   x = *dest;
  ++dest;
  ++src;
}

```

(which itself has problems, but that’s the most literal working interpretation I came up with).

Unfortunately there’s a ton of problems with it:

1. You have to copy the pointer of both src and dest because there’s no way to recover the starting address (but then that’s why I never increment pointers unless I’m freeing the data – a preference most programmers don’t share).

2. Without parens, it’s hard to tell what operator executes when, that is, is it (\*src)++ or \*(src++)? It’s not hard to figure out, but the construction takes some looking at to figure out.

3. It uses the trick I mentioned in the first paragraph, which is so uncommonly used, and bypasses the concept of using boolean values. No, I don’t mean the bool type, I mean the fact that you’re using a value in a conditional and implicitly assuming 0 is FALSE and !0 is TRUE. This is guaranteed in the C spec, I think, but using a value in a conditional just feels really, really wrong. I guess the annoying bit is that it uses a side-effect rather than a primary effect to get the job done.

(A bug of the form

if (x = 0){}

Is a really fun one to find for newbie programmers, because most of them already forget that = and == aren’t the same. Then the language goes and says “you want to use an assignment of the value 0=FALSE instead of checking for a zero value? OKAY!”).

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [June 7, 2012, 9:47pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/86 "2012-06-07T21:47:44Z")

</div>

The problem with the C copy loop is it’s a very poor way to code something that should have been done with the strcpy() function.

---

<div class="post-metadata">

**Author:** ![Jragon](https://avatars.discourse-cdn.com/v4/letter/j/e19b73/32.png) [@Jragon](https://boards.straightdope.com/u/Jragon)\
**Post date:** [June 7, 2012, 9:50pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/87 "2012-06-07T21:50:45Z")

</div>

> [@TriPolar](#):
>
> The problem with the C copy loop is it’s a very poor way to code something that should have been done with the strcpy() function.

Well, what if you have no standard library functions, then what\*? 😛

- There are some compilers that target old video game consoles. They lack library functions to the degree that you have to write the print functions yourself with asm blocks.

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [June 7, 2012, 10:02pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/88 "2012-06-07T22:02:07Z")

</div>

> [@Jragon](#):
>
> Well, what if you have no standard library functions, then what\*? 😛
> 
> - There are some compilers that target old video game consoles. They lack library functions to the degree that you have to write the print functions yourself with asm blocks.

Then you add a comment explaining what you’re doing.

---

<div class="post-metadata">

**Author:** ![Kevbo](https://avatars.discourse-cdn.com/v4/letter/k/e47774/32.png) [@Kevbo](https://boards.straightdope.com/u/Kevbo)\
**Post date:** [June 7, 2012, 10:05pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/89 "2012-06-07T22:05:45Z")

</div>

> [@Senegoid](#):
>
> Likewise, to be a good programmer, you have to be good at programming, and you also have to be good at programming SOMETHING. If you are going to write financial software, you have to be good at programming AND you have to know all about accounting or whatever financial specialty you are into.

This. My Father worked for a railroad. In the early 1970’s they wanted to computerize the scheduling and control of trains. This was formerly done manually by dispatchers. They tried twice to hire computer experts to come up with programs that could do this task, and both were complete failures. Finally they took their 3 best dispatchers and sent them off for six months to learn to program computers, and they were finally able to get something working.

Those dispatchers knew how to do their jobs through experience. They couldn’t explain to anyone else how to do it, and in many cases didn’t consciously even know how they did it. There was no possible way for them to explain to a programmer that didn’t know anything about train dispatching what was needed.

If you really understand the problem you are trying to solve, then you can probably get something working even if you are a terrible programmer. A good programmer will also have something that is easy to understand, debug and maintain. But if you don’t understand the problem you are trying to solve, then you may never get this wonderful program to work right.

---

<div class="post-metadata">

**Author:** ![Chronos](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/chronos/32/134_2.png) [@Chronos](https://boards.straightdope.com/u/Chronos)\
**Post date:** [June 7, 2012, 10:12pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/90 "2012-06-07T22:12:53Z")

</div>

And as another nitpick, couldn’t the empty braces be replaced by a single semicolon?

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [June 7, 2012, 10:23pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/91 "2012-06-07T22:23:28Z")

</div>

> [@Chronos](#):
>
> And as another nitpick, couldn’t the empty braces be replaced by a single semicolon?

Yes. But then it wouldn’t be structured 😃

---

<div class="post-metadata">

**Author:** ![JohnGalt](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/johngalt/32/184_2.png) [@JohnGalt](https://boards.straightdope.com/u/JohnGalt)\
**Post date:** [June 7, 2012, 10:23pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/92 "2012-06-07T22:23:40Z")

</div>

> [@TriPolar](#):
>
> The problem with the C copy loop is it’s a very poor way to code something that should have been done with the strcpy() function.

The reason I teach my C/C++ students \*while (\*dest++ = _src++);_ is they may encounter it in old code written by someone else. It’s certainly easier to understand it in an introductory class than to spend a day or two trying to figure it out by yourself. My hope that they’d finally be able to say “oh! that’s strcpy()!”.

---

<div class="post-metadata">

**Author:** ![Indistinguishable](https://avatars.discourse-cdn.com/v4/letter/i/90ced4/32.png) [@Indistinguishable](https://boards.straightdope.com/u/Indistinguishable)\
**Post date:** [June 7, 2012, 10:27pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/93 "2012-06-07T22:27:06Z")

</div>

> [@TriPolar](#):
>
> Yes. But then it wouldn’t be structured 😃

Er, why? Surely structured programming was never about such syntactic minutiae as whether “;” was an acceptable abbreviation for an empty code block.

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [June 7, 2012, 10:31pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/94 "2012-06-07T22:31:59Z")

</div>

> [@Indistinguishable](#):
>
> Er, why? Surely structured programming was never about such syntactic minutiae as whether “;” was an acceptable abbreviation for an empty code block.

You noticed the smiley face right? Er, I should have used the sarcasm thing.

Anyway, some people consider code structure just to be syntactical form, with no regard to the actual process. So I was mocking that attitude.

---

<div class="post-metadata">

**Author:** ![Senegoid](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/senegoid/32/6606_2.png) [@Senegoid](https://boards.straightdope.com/u/Senegoid)\
**Post date:** [June 7, 2012, 10:43pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/95 "2012-06-07T22:43:49Z")

</div>

> [@Sicks\_Ate](#):
>
> It’s great! Keep it going…it’s on its way to being one of my more successful threads, which is funny because I was expecting it to be over after about post #4.
> 
> I have started looking up some things so I don’t have to ‘Grrrrwhatretheytalkinbout’.

Then y’oughtta try to find some of our earlier threads like this. I try to find some and post links a little later on this afternoon, but I gotta run right now . . .

---

<div class="post-metadata">

**Author:** ![erislover](https://avatars.discourse-cdn.com/v4/letter/e/71e660/32.png) [@erislover](https://boards.straightdope.com/u/erislover)\
**Post date:** [June 7, 2012, 10:45pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/96 "2012-06-07T22:45:18Z")

</div>

I swear C++ programmers have destroyed the utility of every distinction so that it can apply to C++ as a programming language. OO? We’ve got that! Strong typing? We’ve got that! Not like those _scripting_ languages… And to be sure they get it both ways they then permit overloading and implicit conversions… ugh.

The fact is, most languages have strong typing in the sense that every value has a well-defined type. Variables _may_ have types, but they don’t have to. For instance, lisps in general are strongly typed—that is, for one interpretation, there is a predicate which can test a value; and, every value has a predicate. (A different interpretation might be: no expression will be evaluated if it doesn’t type-check, though C cannot guarantee this interpretation.) Here’s an example from an interactive session in Racket:

```auto

> (define a 10)
> (integer? a)
#t
> (set! a "a string")
> (integer? a)
#f
> (string? a)
#t
> 

```

For languages without predicates (e.g., C), you would have to rely on declared types. In this sense, C collapses the variable/value distinction—at least as far as types are concerned. Unfortunately C also collapses other things making it rather unsafe. (Though it is not hard to see that this is a feature of C; less so of C++.)

For other languages, a value might be able to be interpreted in multiple ways. Wikipedia gives the example of PHP interpreting “1000” and “1e3” as equal numbers but unequal strings (ugh) and if this isn’t weak typing I don’t know what would be. I don’t know much about Perl, perhaps it does this sort of nonsense, too.

---

<div class="post-metadata">

**Author:** ![Indistinguishable](https://avatars.discourse-cdn.com/v4/letter/i/90ced4/32.png) [@Indistinguishable](https://boards.straightdope.com/u/Indistinguishable)\
**Post date:** [June 7, 2012, 10:46pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/97 "2012-06-07T22:46:05Z")

</div>

> [@TriPolar](#):
>
> You noticed the smiley face right? Er, I should have used the sarcasm thing.
> 
> Anyway, some people consider code structure just to be syntactical form, with no regard to the actual process. So I was mocking that attitude.

Ah, alright.

---

<div class="post-metadata">

**Author:** ![Senegoid](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/senegoid/32/6606_2.png) [@Senegoid](https://boards.straightdope.com/u/Senegoid)\
**Post date:** [June 7, 2012, 10:49pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/98 "2012-06-07T22:49:45Z")

</div>

> [@TriPolar](#):
>
> Not really. It’s a comparison operation that occurs after the copy is done. But you are wise to avoid pre- and post-increments. They are artifacts of the DEC instruction set and can cause confusion. Efficiency is rarely an issue anymore, clarity always is.

YES and NO !!!  
It DOES matter that the ++ are after the variables instead of before. If you put them before, they’d get incremented before the byte got copied, and the byte copied in each iteration would get copied from/to the wrong place!

And your (ETA: and **Chronos** ) solution (always put increments on a statement by themselves) is, IMHO, the absolute best clear-cut unambiguous foolproof correct way to do it! (But what do I know? I’m an old FORTRAN programmer, where you didn’t have ++ operators.)

Clarity? What clarity? We don’t need no steenkin’ clarity! That snippet I showed from K&R is, like I said, one of the worst examples I’ve seen, especially coming from The Original Source Of All C !

I’ve only glanced at the other subsequent posts so far. At first glance, I do suspect that I’m right: Most of you don’t know what that awfully-written code really does. But give me a chance to read your posts more carefully first. Later this afternoon. I gotta run now . . .

---

<div class="post-metadata">

**Author:** ![Senegoid](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/senegoid/32/6606_2.png) [@Senegoid](https://boards.straightdope.com/u/Senegoid)\
**Post date:** [June 7, 2012, 10:54pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/99 "2012-06-07T22:54:00Z")

</div>

> [@TriPolar](#):
>
> The problem with the C copy loop is it’s a very poor way to code something that should have been done with the strcpy() function.

You missed the point (if you read K&R): That IS the strcpy() function!

---

<div class="post-metadata">

**Author:** ![Senegoid](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/senegoid/32/6606_2.png) [@Senegoid](https://boards.straightdope.com/u/Senegoid)\
**Post date:** [June 7, 2012, 11:04pm UTC](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300/100 "2012-06-07T23:04:17Z")

</div>

Okay, quick answer before I gotta run . . .

I’m not sure if any of the above posts really fully got this, although on quick glance I see that some were at least leaning in the right direction. I’ll read them all more thoroughly later this afternoon.

That one-line string copy is an abomination of structured programming because it does exactly what structured program is NOT supposed to do – or, from another point of view, it does exactly what that kind of while ( ) loop is specifically designed NOT to do.

That kind of while ( ) loop is SPECIFICALLY specified to create a “top-controlled” loop – That is, the very FIRST thing it does in each iteration is to test the condition, and then skip out if false. How, then, does it copy up to _and including_ the zero byte, rather than stopping at the zero byte before copying it?

Because the copy operation (as well as both the incrementing operations) are done in the processing of evaluating the conditional, BEFORE actually testing the result of that conditional. In other words, this code semi-surreptitiously puts some actual do-something code BEFORE the conditional test. In other words, in the guise of being a top-controlled loop, it is not a top-controlled loop at all! In fact, it puts ALL its do-something code before the test, effectively making it a bottom-controlled loop (which has the test at the end of each iteration instead of the beginning).

It took me a good 45 minutes of studying that one line of code, the first time I saw it, to figure that out! And that, IMHO, is a total mis-use and abuse of the very purpose and intention of the while ( ) loop!

[Previous page](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300.md?page=4)

[Next page](https://boards.straightdope.com/t/extremeely-basic-programming-question/624300.md?page=6)
