News for hackers. Stuff that matters.
Re:Modern C [pdf] by colanderman on Monday November 28, 2016 @10:43AM (#13056088)
While I like a lot of what's in here,

    for (size_t i = 9; i <= 9; --i)
is a pretty terrible example to put in the second chapter. I would not let that line pass code review. There is no need or place for cutesy cleverness in C.

EDIT: Ugh, just found this too:

    isset[!!largeA[i]] += 1;
Not only is that confusingly cutesy, but largeA[i] is a double. Please DON'T write – or encourage beginners to write! – such smug code!

EDIT2: In section 5 is the statement than unsigned integers "can be optimized best." This is flatly untrue on x86 and I suspect many other architectures. Compilers can and do take advantage of undefined signed overflow to optimize signed arithmetic; the same is not possible with unsigned arithmetic. See https://kristerw.blogspot.com/2016/02/how-undefined-signed-o...

Re:Modern C [pdf] by cygx on Monday November 28, 2016 @11:11AM (#13056290)
I would not let that line pass code review.

Obviously. However, it is an appropriate example if your goal is to teach the intricacies of the C language. You're right that if you provide such an example this early, it could perhaps use some additional commentary.

Not only is that confusingly cutesy, but largeA[i] is a double.

That was the point of the exercise: !! is an idiom to convert to boolean (which happen to be integral in C) and something a C programmer (or JavaScript programmer, for that matter) should be familiar with.

This is flatly untrue on x86 and I suspect many other architectures.

Agreed.

Re:Modern C [pdf] by colanderman on Monday November 28, 2016 @11:19AM (#13056354)
I agree they are great examples to test understanding, but if they're going to be present in the first chapter of a pedagogical book, they need a disclaimer. People copy things.
Re:Modern C [pdf] by Nadya on Monday November 28, 2016 @10:54AM (#13056182)
Given the explanatory text - I think this was more of a "test of intuition" accompanied by a "gotcha!"

As someone unfamiliar with C - I initially thought it would go on forever. The explanatory text explained why I was wrong and this can be equally parts "clever code" or a "gotcha!" depending how you view it. With your experience you're seeing it as overly clever code. With mine, I'm seeing it as a "gotcha". I don't think it is supporting writing code like that. :)

>The third for appears like it would go on forever, but actually counts down from 9 to 0. In fact, in the next section we will see that “sizes” in C, that is numbers that have type size_t, are never negative.

Re:Modern C [pdf] by yoha on Monday November 28, 2016 @11:08AM (#13056265)
Decrementing loops is the one place where I have indulged in some trickery. I do:

    for (size_t i = 9; i --> 0; )
This has the advantage to be very easy to pattern-match once known. Obviously, for a beginner, I would just do:

    for (int i = 9; i >= 0; i -= 1)
Re:Modern C [pdf] by colanderman on Monday November 28, 2016 @11:16AM (#13056327)
Everyone should write your second example. The first does nothing but confuse. C has enough hazing rituals without garbage like "-->".

The fewer tricks and patterns you use in C, the higher chance actual bugs have of being caught. Cutesy tricks like "-->" confuse human analysis and gain nothing.

Re:Modern C [pdf] by yoha on Monday November 28, 2016 @11:27AM (#13056422)
This is about weighing correction versus readability. In the "arrow operator" version, the readability is decreased; in the "proper" version, a type cast is required, and this can lead to bugs with values greater than 2^sizeof(ssize_t).

Obviously, I just follow the convention when contributing to an existing project.

Re:Modern C [pdf] by cygx on Monday November 28, 2016 @11:38AM (#13056498)
this can lead to bugs with values greater than 2^sizeof(ssize_t)

The range of indexable array elements is not only constrained by the unsigned type size_t, but also by the signed type ptrdiff_t, so you could always go with the latter instead of the non-ISO ssize_t.

Re:Modern C [pdf] by pwdisswordfish on Monday November 28, 2016 @11:34AM (#13056470)
...values greater than 10?
Re:Modern C [pdf] by FloDo on Monday November 28, 2016 @03:25PM (#13058095)
Do you even realize that these two loops are not equivalent? One of them starts at 8, then other one starts at 9 ...
Re:Modern C [pdf] by yoha on Tuesday November 29, 2016 @01:25AM (#13061283)
Right, my bad. I tend to write loops in the former style, thinking of them as reversed(range(9)). This is another advantage of this style. I should have been more cautious when writing the second one.
Re:Modern C [pdf] by kLeeIsDead on Monday November 28, 2016 @07:06PM (#13059547)
That first example reads like a horrible pun.
Re:Modern C [pdf] by timow1337 on Monday November 28, 2016 @01:50PM (#13057493)
now do the second example with an unsigned type.
Re:Modern C [pdf] by yoha on Monday November 28, 2016 @01:57PM (#13057538)
The point is that a beginner does not need to care about signedness. When you get to that point, you can take the time to explain how to loop properly over it.
Re:Modern C [pdf] by imron on Monday November 28, 2016 @11:05AM (#13056250)
> I would not let that line pass code review.

At least it's not

    for (size_t i = 9; i >= 0; --i)
:-)
Re:Modern C [pdf] by colanderman on Monday November 28, 2016 @11:17AM (#13056339)
I agree. For this reason I wish the author would promote (no pun intended) the use of signed arithmetic.
Re:Modern C [pdf] by renlo on Monday November 28, 2016 @04:08PM (#13058436)
Your for loop works, whereas the one in the parent comment would run forever, correct? Is there something I'm missing here?

edit: Ok, looking at it again the parent example is probably going to overflow or something right?

Re:Modern C [pdf] by cygx on Monday November 28, 2016 @04:26PM (#13058573)
Your for loop works, whereas the one in the parent comment would run forever, correct?

The other way around: size_t is an unsigned type, so decrementing 0 will wrap around to SIZE_MAX, a value that is positive as well as greater than 9. This means counter to your intuition, the first loop will terminate and the second one won't.

Re:Modern C [pdf] by imron on Tuesday November 29, 2016 @05:24AM (#13062147)
> Is there something I'm missing here?

Yes (see other replies), and it's precisely the reason why this code shouldn't pass code review.

At first glance the first example looks like it should fail but in fact works. The second example I provided looks like it should work, but in fact loops infinitely.

The first one is tricky and nifty, but prone to bugs. Using signed counters is better way to go about it.

Re:Modern C [pdf] by clarkcox3 on Monday November 28, 2016 @04:49PM (#13058733)
The example with ">= 0" is an infinite loop, a size_t will always be greater than or equal to zero; it's unsigned.