Live data from Hacker News

Essential C (2003) [pdf]

cslibrary.stanford.edu

81–84 of 84 posts

Re: Essential C (2003) [pdf]

#81
post #71
post #41

Earlier quoted context omitted.

ptrdiff_t exists for subtraction between pointers that produce negative values. But how many times have you ever needed to subtract p and q where p represents an array element at a higher index than q? For that matter, how many times have you ever needed to add a negative integer to a pointer? In C an object can be larger than PTRDIFF_MAX, a real possibility in modern 32-bit environments. (Some libc's have been modif…

Negative offset is used often to access fields in parent struct having pointer to a field only. For example, to implement garbage collection or string type.

But p - 2 is not the same as p + -2, and it's not clear in your example whether the former suffices or the latter is required. I can definitely imagine examples where the latter is required--certainly C clearly accommodates this usage--but IME it's nonetheless a rare scenario and not something that could, alone, justify always using signed offsets. Pointers are intrinsically neither signed nor unsigned; it's how you use them that matters.

Re: Essential C (2003) [pdf]

#82
post #71
post #41

Earlier quoted context omitted.

ptrdiff_t exists for subtraction between pointers that produce negative values. But how many times have you ever needed to subtract p and q where p represents an array element at a higher index than q? For that matter, how many times have you ever needed to add a negative integer to a pointer? In C an object can be larger than PTRDIFF_MAX, a real possibility in modern 32-bit environments. (Some libc's have been modif…

Negative offset is used often to access fields in parent struct having pointer to a field only. For example, to implement garbage collection or string type.

That should be:

  Parent* p = container_of(field,Parent,pa_somefield);
  access(p->pa_otherfield);
You'd usually define container_of using subtraction (not negative offset per se):

  #define container_of(FIELD,TYPE,MEMB) ({ \
   const typeof( ((TYPE*)0)->MEMB )* _mptr = (FIELD); \
   (TYPE*)( (char*)_mptr - __builtin_offsetof(TYPE,MEMB) ); \
   })
but you shouldn't actually be using that directly, because thats what the macro is for.

Re: Essential C (2003) [pdf]

#83
"Teach Yourself C in 24 Hours" by Tony Zhang (1997) seems interesting as well:

http://aelinik.free.fr/c/

A previous HN discussion on that book:

https://news.ycombinator.com/item?id=15624521

EDIT: That earlier discussion has an excellent first post. Quoting:

"It bothers me so much that very few books (Kernighan) talk about WHY. WHY. WHY is a variable needed? WHY is a function needed? WHY do we use OOP? Every single book out there jumps straight into explaining objects, how to create them, constructors, blah blah blah. No one fricking talks about what's the point of all this?

Teaching syntax is like muscle memory for learning Guitar. It is trivial and simply takes time. Syntax - everyone can learn and it is only one part of learning how to code. Concepts are explained on their own without building upon it.

[... A list with learning resources the poster finds great ...]

This is learning how to produce music. Not learning the F chord. Teaching how to code is fundamentally broken and very few books/courses do it well."

Re: Essential C (2003) [pdf]

#84
post #41
post #24

Earlier quoted context omitted.

In C an index is a difference that you add to a pointer to get a pointer. `a[i]` is `*(a + i)`. Given two indices `i` and `j`, you want `i - j` to be such that `a[j + (i - j)]` is `a[i]`, and it then makes sense to me that `i - j` is signed. The expression works out whether they are signed or unsigned, but just in terms of their interpretation on the part of a user (eg. "oh this is 2 elements before bc. it says -2")…

ptrdiff_t exists for subtraction between pointers that produce negative values. But how many times have you ever needed to subtract p and q where p represents an array element at a higher index than q? For that matter, how many times have you ever needed to add a negative integer to a pointer? In C an object can be larger than PTRDIFF_MAX, a real possibility in modern 32-bit environments. (Some libc's have been modif…

The reason we are in this subthread is my message about being bitten by unsigned underflow when iterating backwards using an unsigned `i`.
Post reply on HN