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…
Essential C (2003) [pdf]
71–80 of 84 posts
Re: Essential C (2003) [pdf]
#72Topics:
* Best practices for C function signatures (caller allocates (which size?), callee allocates (where? which allocator?))
* Memory Ownership Models
* Borrowing
* Reference Counting
* Garbage Collectors and C-Libraries providing this functionality
* Interning Objects (Strings)
* RAII [1]? And it's benefits/flaws
[1] https://en.wikipedia.org/wiki/Resource_acquisition_is_initia...
Context: I feel that understanding the C memory primitives in not that hard (stack variables, malloc/free, C++'s new). But how to use them is devilishly tricky. I have seen little information about this.
Re: Essential C (2003) [pdf]
#73While we are here, does anyone have a good resource about memory management strategies in C? Topics: * Best practices for C function signatures (caller allocates (which size?), callee allocates (where? which allocator?)) * Memory Ownership Models * Borrowing * Reference Counting * Garbage Collectors and C-Libraries providing this functionality * Interning Objects (Strings) * RAII [1]? And it's benefits/flaws [1] http…
This generally discusses the lack of RAII in C (towards the end), and what to do about it:
https://floooh.github.io/2019/09/27/modern-c-for-cpp-peeps.h...
...and this presents a (reasonably runtime-safe) general memory management strategy using tagged-index-handles instead of pointers:
https://floooh.github.io/2018/06/17/handles-vs-pointers.html
The gist is basically:
- don't allocate small chunks of memory all over the code base, instead move memory management into few centralized systems, and let those systems own all memory they allocate
- don't use pointers as public "object references", instead use "tagged index handles"
- don't use "owning pointers" at all, use pointers only as short-lived "immutable borrow references"
Re: Essential C (2003) [pdf]
#74While we are here, does anyone have a good resource about memory management strategies in C? Topics: * Best practices for C function signatures (caller allocates (which size?), callee allocates (where? which allocator?)) * Memory Ownership Models * Borrowing * Reference Counting * Garbage Collectors and C-Libraries providing this functionality * Interning Objects (Strings) * RAII [1]? And it's benefits/flaws [1] http…
Shameless plug: This generally discusses the lack of RAII in C (towards the end), and what to do about it: https://floooh.github.io/2019/09/27/modern-c-for-cpp-peeps.h... ...and this presents a (reasonably runtime-safe) general memory management strategy using tagged-index-handles instead of pointers: https://floooh.github.io/2018/06/17/handles-vs-pointers.html The gist is basically: - don't allocate small chunks of…
Re: Essential C (2003) [pdf]
#75Earlier quoted context omitted.
I typically see Rust marketed as a better replacement for C. In what cases isn't it a practical replacement?
Rust is a fine replacement for C++, but not really for C, and the reasons why Rust can't be a replacement for C are very similar to why C++ can't be a replacement for C. Everybody who chooses C today has slightly different reasons to do so, but one important reason is that C is a very small language with a very small standard library, and most parts of the standard library can be ignored without losing any of the "qu…
Re: Essential C (2003) [pdf]
#76Re: Essential C (2003) [pdf]
#77Earlier quoted context omitted.
> Make sure it's a one line block that is totally unbraced with only single letter variable names if you do it because otherwise it's just faux-macho C and that's /weak/. I think you're projecting. The point being made was that when you're writing a simple stack (as you often might do in C, since the standard library and the language itself conspire against providing you one) and you don't have the overhead to write…
Sorry no. That's not for you in particular that's just a general comment on macho C, which I think we've all seen. int abc(int a, int b, int c) { } I can do postincrement. I learned C the macho way. We all still have to read that crap. Now I know better when I'm writing it. I strongly disagree that a = *stack--; *++stack = b is better in any way beyond "I'm a macho C guy" than a = pop_int(); push_int(b); https://en.w…
I agree with saagarjha, there is nothing unclear or "crap" about using basic operators in an idiomatic way.
Re: Essential C (2003) [pdf]
#78Earlier quoted context omitted.
Sorry no. That's not for you in particular that's just a general comment on macho C, which I think we've all seen. int abc(int a, int b, int c) { } I can do postincrement. I learned C the macho way. We all still have to read that crap. Now I know better when I'm writing it. I strongly disagree that a = *stack--; *++stack = b is better in any way beyond "I'm a macho C guy" than a = pop_int(); push_int(b); https://en.w…
Now the stack pointer is hidden. Is there only a single global stack? I agree with saagarjha, there is nothing unclear or "crap" about using basic operators in an idiomatic way.
But this is as much beside the point under discussion as global pointers you raise.
Post-increment is an artefact from PDP-11 assembler and maps to a single instuction there. That's where it came from quite directly. It's completely unnecessary. Most modern languages find it useless enough they remove it. Python goes fine without it relying on +=, for example. (Although some do repeat C mistakes when basing their syntax on C, eg the unbraced, single line block that serves only to add non-zero probability of introducing a future bug but with the benefit of precisely nothing.. Hi Walter! Larry Wall cops flack for Perl syntax but he did not copy that.)
Post increment is hardly the end of the world it just isn't useful. It doesn't help readability. It can harm it. As a question of taste I find it lacking.
But hey, everyone else uses it, and duff's device is fun to read so go with them, knock yourself out.
Re: Essential C (2003) [pdf]
#79This guide is short (which is always nice) but not has a couple of flaws in places in the brief skim I gave it. For example: > In particular, if you are designing a function that will be implemented on several different machines, it is a good idea to use typedefs to set up types like Int32 for 32 bit int and Int16 for 16 bit int. Use please > The char constant 'A' is really just a synonym for the ordinary integer val…
> Not a problem, but :(
In a declaration, * is a type modifier. E.g. `int a;` declares a variable of type "int" named "a". `int* a;` declares a variable of type "pointer to int" named "a".
The only time this doesn't work is if you stick multiple declarations on the same line. That's annoying to me, because it means you're breaking the "declare variables as close to their first use as possible" practice. It's not K&R C any more, you don't need to declare everything all at once at the top of the scope.
Also, to prove that `` in a declaration is part of the type, note that K&R style function declarations (no argument names, just types) are still valid C (though I'd strongly discourage their use). So `void func(int a, int b);` is identical to `void func(int, int);`. It's very different from `void func(int, int);` that you'd get if you assume the `` goes with the `a`.
Re: Essential C (2003) [pdf]
#80While we are here, does anyone have a good resource about memory management strategies in C? Topics: * Best practices for C function signatures (caller allocates (which size?), callee allocates (where? which allocator?)) * Memory Ownership Models * Borrowing * Reference Counting * Garbage Collectors and C-Libraries providing this functionality * Interning Objects (Strings) * RAII [1]? And it's benefits/flaws [1] http…
Shameless plug: This generally discusses the lack of RAII in C (towards the end), and what to do about it: https://floooh.github.io/2019/09/27/modern-c-for-cpp-peeps.h... ...and this presents a (reasonably runtime-safe) general memory management strategy using tagged-index-handles instead of pointers: https://floooh.github.io/2018/06/17/handles-vs-pointers.html The gist is basically: - don't allocate small chunks of…