Earlier quoted context omitted.
typedef struct {uint8_t *data; size_t len;} ByteBuf; is the first line of code I write in a C project.
Could you add some extra information why this is so helpful or handy to have? Think it will benefit readers that are starting out with C etc.
Tell HN: C Experts Panel – Ask us anything about C
841–850 of 978 posts
Re: Tell HN: C Experts Panel – Ask us anything about C
#842Earlier quoted context omitted.
The problem in practice is that you do not write “hello” and “world” to the destination buffer. You write data that is computed more or less directly from user inputs. Often a malicious user. So the user only needs to find a way to make the data longer than the developer expected. This may be very simple: the developer may have written a screensaver to accept 20 characters for a password, because who has a longer pas…
I think sprintf and gets can be perfectly secure interfaces. The standard just needs to specify them in a way that causes overflows to raise signals. This is probably more for POSIX and UNIX, since I think it requires the concept of memory mappings. For example: Start by specifying that memcpy goes by increasing address. This can be done by specifying that no pages to be written by memcpy can be written to until afte…
Re: Tell HN: C Experts Panel – Ask us anything about C
#843Earlier quoted context omitted.
Maybe someone else can respond to this as well, but I feel like the primary reason signed overflow is still undefined behavior is because so many optimizations depend upon the undefined nature of signed integer overflow. My advice has always been to use unsigned integer types when possible. Personally, I would like to get rid of many of the trap representations (e.g., for integers) because there is no existing hardwa…
> My advice has always been to use unsigned integer types when possible. Unsigned types have their own issues, though: they overflow at "small" values like -1, which means that doing things like correctly looping "backwards" over an array with an unsigned index is non-trivial. > On the other hand, I just wrote a proposal to WG14 to make zero-byte reallocations undefined behavior that was unanimously accepted for C2x.…
Re: Tell HN: C Experts Panel – Ask us anything about C
#844Earlier quoted context omitted.
I disagree, because they return a value that nobody really wants and thus perform poorly: https://saagarjha.com/blog/2020/04/12/designing-a-better-str...
So standardize them as returning void — great!
Re: Tell HN: C Experts Panel – Ask us anything about C
#845Is memset(malloc(0), 0, 0) undefined behavior?
Let's assume the types have been corrected. malloc((size_t)0) behavior is defined by the implementation; there are two choices: (a) always returns a null pointer; or (b) acts like malloc((size_t)1) which can allocate or fail, and if it allocates then the program shall not try to reference anything through the returned non-null pointer. Now, memset itself is required (among other things) to be given as its first argum…
Re: Tell HN: C Experts Panel – Ask us anything about C
#846Earlier quoted context omitted.
Let's assume the types have been corrected. malloc((size_t)0) behavior is defined by the implementation; there are two choices: (a) always returns a null pointer; or (b) acts like malloc((size_t)1) which can allocate or fail, and if it allocates then the program shall not try to reference anything through the returned non-null pointer. Now, memset itself is required (among other things) to be given as its first argum…
What observable difference is there between malloc(0) and malloc((size_t)0)?
Re: Tell HN: C Experts Panel – Ask us anything about C
#847Re: Tell HN: C Experts Panel – Ask us anything about C
#848Earlier quoted context omitted.
My idea was to add something like the GoLang defer statement to C (as a function with some special compiler magic). The following is an example of how such a function could be used to cleanup allocated resources regardless of how a function returned: int do_something(void) { FILE *file1, *file2; object_t *obj; file1 = fopen("a_file", "w"); if (file1 == NULL) { return -1; } defer(fclose, file1); file2 = fopen("another…
Go-like defer() is easily implementable for C using the asm() keyword. Here's an example of how it can be done for x86: https://gist.github.com/jart/aed0fd7a7fa68385d19e76a63db687f...
Also it's function-level (like golang) not scope-level (like attribute cleanup). As argued elsewhere in the this thread, golang got this wrong.
Also also, overwriting the return address on the stack kills internal CPU optimizations that both Intel and AMD do for branch prediction.
Re: Tell HN: C Experts Panel – Ask us anything about C
#849Re: Tell HN: C Experts Panel – Ask us anything about C
#850 _If, _Ifdef, _Ifndef
inside function macrosfor example:
#ifdef SOME_CONST
#define WHATEVER(w, h, a, t, e, v, e, r) \
... common part ... \
... for SOME_CONST ... \
... common part continued ...
#else
#define WHATEVER(w, h, a, t, e, v, e, r) \
... common part ... \
... when SOME_CONST not defined ... \
... common part continued ...
#endif
With _Ifdef, the above could be written like: #define WHATEVER(w, h, a, t, e, v, e, r) \
... common part ... \
_Ifdef(SOME_CONST, \
(... for SOME_CONST ...) , \
(... when SOME_CONST is not defined ...)
) \
... common part continued ...
With these, one could also do: #define FACTORIAL(n) _If(n == 0, 1, (n) * FACTORIAL(n))
int f = FACTORIAL(6);
turns into:
int f = (6) * (5) * (4) * (3) * (2) * (1) * 1;That would be very useful, I think. It might help with code duplication in function macros.
Maybe _Switch/_Case thereafter.