Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Activity for alx
Type | On... | Excerpt | Status | Date |
---|---|---|---|---|
Comment | Post #286605 |
You're welcome! :-)
However, I'd rather recommend my newer answer, which has a much easier user experience (although it requires a specific MUA: neomutt(1); unless you find another one that works similarly):
<https://software.codidact.com/posts/286573/291329#answer-291329> (more) |
— | 2 days ago |
Comment | Post #286588 |
But me as a maintainer or co-maintainer of several widely-used FOSS projects? I'd say at least a worrying little bit. (more) |
— | 2 days ago |
Comment | Post #286588 |
I didn't know of any, but I recently patched neomutt(1) to behave like that. See my new answer: <https://software.codidact.com/posts/286573/291329#answer-291329>
Usage:
`.gitconfig`:
```
[sendemail]
sendmailcmd = neomutt -C -H - && true
``` (more) |
— | 11 days ago |
Comment | Post #286588 |
If such a malicious sender uses the `Reply-To` header field, as in this example:
```
From: well-known@example.com
Reply-To: well-known@foo.com
```
That reply-to address may look like a valid alternative address of the sender, and really be an address of an attacker.
As long as the imperso... (more) |
— | 11 days ago |
Comment | Post #290316 |
@#8176 You can't, in the sense that the expression won't be undefined (because `#undef` is interpreted by the preprocessor, there are still no identifiers that aren't macros; it's just text), but you can, in the sense that your program will be valid.
```c
#undef stdin
#define stdin something_els... (more) |
— | 4 months ago |
Comment | Post #290316 |
@#8176 A minor nitpick on your comment: `#undef` doesn't need to be guarded by `#ifdef`. `#undef` is defined by ISO C to be a no-op if there's no such macro. <http://port70.net/~nsz/c/c11/n1570.html#6.10.3.5p2> (more) |
— | 4 months ago |
Comment | Post #290215 |
Very interesting hacks about commas with macros! I'd say if you write a macro that expands to something with a comma operator, you either want that hack explicitly for some obscure reason, or should be using parens in that macro so that it doesn't misbehave with other macros. But yeah, very interes... (more) |
— | 6 months ago |
Comment | Post #290215 |
But in function argument lists, the comma operator cannot appear, so in a replacement, the comma operator will never appear in the top level, right?
That is, how can I embed a comma operator in a macro call that could possibly interfere with the macro body?
```c
macro(a, (b, c));
```
That ... (more) |
— | 6 months ago |
Comment | Post #277341 |
C has the #error directive, and C23 will have the #warning directive.
<https://www.open-std.org/JTC1/SC22/WG14/www/docs/n2686.pdf> (more) |
— | 7 months ago |
Comment | Post #289497 |
Sorry for not mentioning you. @#8176 (more) |
— | 7 months ago |
Comment | Post #289415 |
@#8176
In the case of `{0}`, it looks rather weird. But imagine this structure:
```
auto struct s {
int8_t x;
int32_t y;
} s = {.x = foo, .y = bar};
```
Initializing the padding could make it slower. I agree that the standard could have special-cased `{0}`, since anyway it'... (more) |
— | 7 months ago |
Comment | Post #289415 |
Here's an example:
```c
struct s2 {
int8_t c;
int32_t i;
};
struct s1 {
int8_t c;
int32_t i;
struct s2 s;
};
void f(void)
{
struct s1 x = {0};
}
```
The padding within `x` itself would not be zeroed, but the padding within `x.s` would be zeroed (because `x... (more) |
— | 7 months ago |
Comment | Post #289415 |
@#8176 I got a quick response from JeanHeyd. The standard seems unclear in the wording, and a reasonable interpretation could be that (some) padding is not zeroed. I'll clarify below the quotes.
6.7.9p21 "If there are fewer initializers in a brace-enclosed list than there are elements or members... (more) |
— | 7 months ago |
Comment | Post #278658 |
Regarding POSIX rationale, I don't know. Their website puts me off with several layers of registration and nonsense. (more) |
— | 7 months ago |
Comment | Post #278658 |
7.19p3 <http://port70.net/~nsz/c/c11/n1570.html#7.19p3> says "[NULL] expands to an implementation-defined null pointer constant".
I thought the text in there allows anything in `NULL`, and isn't restricted by 6.3.2.3p3 (which you quoted).
I interpret 6.3.2.3p3 as saying that you can use any of ... (more) |
— | 7 months ago |
Comment | Post #289415 |
Agree. That blog seems wrong (I'll write to JeanHeyd later). This morning I was a bit dense, and didn't find the relevant paragraph. 6.7.9p21 seems to be it <http://port70.net/%7Ensz/c/c11/n1570.html#6.7.9p21>
So, it seems both `{0}` and `{}` do the right thing for pointers, and so does implici... (more) |
— | 7 months ago |
Comment | Post #281519 |
I prefer the name strlcpy() rather than strcpy_s(), since it's not inherently safer, but just a different function. (more) |
— | 7 months ago |
Comment | Post #289415 |
(D'oh! yep, I meant a null pointer. You're right being pedantic. :)
Hmm, sorry, for some reason I thought `{0}` was shorthand for memset(3). It isn't.
Nevertheless, the wording in the answer "equivalent to initializing everything to zero" is technically wrong, I'd say, since the word zero do... (more) |
— | 7 months ago |
Comment | Post #278658 |
ISO C allows any kind of garbage in NULL, such as `0`, or `(void *)-1`. However, POSIX mandates that it be "an integer constant expression with the value `0` cast to type `void *`".
This is helpful if all you care about is POSIX. Not so much if you don't. (more) |
— | 7 months ago |
Comment | Post #289415 |
Re: freestanding: Heh, I guess. :) But maybe being in POSIX helps get it into ISO C... in a decade or two :D (more) |
— | 7 months ago |
Comment | Post #281519 |
I recently wrote string_copying(7), which discusses all standard functions that have been historically used for copying strings (even if incorrectly), and also suggests some non-standard interfaces for some cases.
<https://man.archlinux.org/man/string_copying.7.en> (more) |
— | 7 months ago |
Comment | Post #281519 |
strlcpy(3) will be blessed by POSIX in Issue 8 (that is, POSIX.1-202x). (more) |
— | 7 months ago |
Comment | Post #289415 |
`memccpy(dest, src, '\0', n)` isn't safer than `strncpy(dest, src, n)`. Neither of those functions guarrantees a string in `dest`. Both functions will fail to terminate `dest` with a `NUL` if it doesn't fit.
In the case of strncpy(3), this is fine, as this function is only appropriate for fixed-... (more) |
— | 7 months ago |
Comment | Post #289415 |
strncpy(3) is still appropriate in some cases: fixed-width character arrays. An example of an interface that uses this is `struct utmp` (see utmp(5)). The fields `utmp::ut_line`, `utmp::ut_user`, and `utmp::ut_host` are _not_ strings, and should not be written with strlcpy(3), nor any other string ... (more) |
— | 7 months ago |
Comment | Post #289415 |
`{0}` initializes to `0`. `{}` initializes to `0`, except pointers, which are initialized to `NULL`. It's pedantic, but in some unicorn implementations it may be meaningful. (more) |
— | 7 months ago |
Comment | Post #289497 |
```c
size_t n, size;
int *p;
n = MIN(PTRDIFF_MAX, SIZE_MAX) - 1; // A huge valid number of elements.
//size = sizeof(int[n]); // Is this even legal?
size = n * sizeof(int); // This wraps around, producing a bogus size.
p = malloc(size); // No UB, but...
if (p)
exit(1);
p[n - 1... (more) |
— | 7 months ago |
Comment | Post #289497 |
Hi Lundin!
I agree the term overflow is incorrectly used in the man(7) page. I invite you to send a patch for that. Please check <https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/CONTRIBUTING>. :) (more) |
— | 7 months ago |
Comment | Post #289891 |
You could maybe use formail(1) in this script too, although I didn't know that tool until today. (more) |
— | 7 months ago |
Comment | Post #289891 |
Let's say I want to move mails from `someone@example.com` to `/dest/dir`:
```sh
print_filenames_that_would_be_moved \
| xargs grep -l '^From: someone@example.com' \
| xargs mv -t /dest/dir
``` (more) |
— | 7 months ago |
Comment | Post #289891 |
Why not do somehting like this?
```sh
print_filenames_that_would_be_moved \
| xargs grep -e '^From: ' -e '^Subject: ' /dev/null
``` (more) |
— | 7 months ago |
Comment | Post #287754 |
Is it? I just came to this question again because of flexible array members.
See <https://gustedt.wordpress.com/2011/03/14/flexible-array-member></https:> for more context.
The allocation is usually one of these:
```c
malloc(sizeof(s) + sizeof_member(s, fam[0]) * N);
malloc(offsetof(s, fa... (more) |
— | 9 months ago |
Comment | Post #288247 |
I think the object pointed to by dest is a `struct t`, not a union, since I use a pointer to the member. Only if I had casted it to the union type, or if I had used the union directly, it would have been the union, I think. (more) |
— | 11 months ago |
Comment | Post #285051 |
You could maybe even constexpr that :) I guess accepting such evilness is due to being more complex to reject, rather than an intention of defining the behavior. Nevertheless, I do think that `param[0]` has a valid use case in pointers to one-past-the-end of an array, which are useful for bounds. (more) |
— | 11 months ago |
Comment | Post #285051 |
You're right. I wish zero-sized arrays get allowed some day in array parameters. :) (more) |
— | 11 months ago |
Comment | Post #285051 |
It might be worth noting that `static` requires that the array size is at least `1`. So, it's not valid C to have `int x[static 0]` as a parameter, which can be otherwise useful as an end-of-array marker.
For example, one may design a function which takes an array and a pointer to one-after-the-l... (more) |
— | 11 months ago |
Comment | Post #288023 |
Regarding VLA notation, is it mandated by the standard, or is it optional? Anyway, I'm not going to complain about good taste extensions to the language:) I'll complain about the real issues of it (IMO): while it solves the readability issues, it doesn't solve type safety. In fact, that's one of t... (more) |
— | about 1 year ago |
Comment | Post #288023 |
As for having to read the definition of the macros: that really goes for any code you read. I don't know why these wrappers would be any different. Encapsulation is not bad (it can be bad, but it's not necessarily bad); especially if it solves a long-standing issue of type safety.
How to read th... (more) |
— | about 1 year ago |
Comment | Post #288023 |
I guess your comment only applies to the macros, and not the Unix-only *array() variants like reallocarray(3), right?
The malloc API is not really horrible; it's good, as far as C functions go. There's really not much more that could be acomplished, in terms of type safety. Overflow due to multi... (more) |
— | about 1 year ago |
Comment | Post #285910 |
The rule for `sizeof(*p)`, at least as I used it in the past, was more like:
```c
SOMETHING = malloc(sizeof(*SOMETHING));
```
Whatever that `SOMETHING` is, the above rule works (except for `flexy`, of course :).
```c
p = malloc(sizeof(*p));
p[i] = malloc(sizeof(*p[i]));
```
---
Di... (more) |
— | about 1 year ago |
Comment | Post #288020 |
Moreover, I've just checked the C2x draft and a proposal that got accepted, and found something that seems to say that this is UB:
Accepted proposal for C2x:
<https://www.open-std.org/JTC1/SC22/WG14/www/docs/n2861.pdf>
C2x (latest draft that I know of):
<https://www.open-std.org/JTC1/SC22... (more) |
— | about 1 year ago |
Comment | Post #288020 |
> since p and q are now indeterminate, nothing can be assumed about them - their values are unspecified.
Nothing can be assumed about the value of p.
> since p used to hold a valid value and since free() can't change p, then p cannot hold a trap representation in this specific case.
Yet we c... (more) |
— | about 1 year ago |
Comment | Post #286189 |
strncat(3) is a good function. It's just that is has been misused. I thought it was a useless broken-by-design function, until I found by chance a good use of it in groff(1)'s source code (https://git.savannah.gnu.org/cgit/groff.git/tree/src/roff/troff/input.cpp?id=f720813c5f512627a246115a255989ad6... (more) |
— | about 1 year ago |
Comment | Post #286189 |
@#8176 linux.die.net has quite outdated versions of the man pages; at least I can confirm that of the Linux man-pages, which I maintain. The only official online version of the Linux man-pages is this PDF: https://mirrors.edge.kernel.org/pub/linux/docs/man-pages/book/man-pages-6.04.01.pdf. There's... (more) |
— | about 1 year ago |
Comment | Post #287083 |
> Someone somewhere might still have the great idea to define a macro called "index" in a public header file...)
And someone might be 4.3BSD and POSIX.1-2001 :D.
It's a function, though, but that already makes it reserved, so I wouldn't call anything `index`, except maybe a structure member.
O... (more) |
— | about 1 year ago |
Comment | Post #287917 |
`int* ptr = original; free(original); if(ptr == original)`: That would actually be different. That one is in fact Undefined Behavior, since you're reading the pointer value and not its representation. To make it unspecified behavior, you's need to call memcmp(3). (more) |
— | about 1 year ago |
Comment | Post #287917 |
I guess using a `free(3)`d pointer in the same way, instead of an uninitialized `int32_t` local, would still be *unspecified* behavior, since we can't trap because `memcmp(3)` uses char to read the representation. Am I correct? I used `int32_t` just to simplify the question, but it's true that `int... (more) |
— | about 1 year ago |
Comment | Post #287908 |
I chose 0 on purpose to avoid endianness issues, and also to make sure I know the translation from representation to value. I could have also chosen maybe `0x1111` or something similar which isn't affected by endianness, but `0` was just simpler.
I'm almost sure representation 0 has to correspond... (more) |
— | about 1 year ago |
Comment | Post #287908 |
memcmp(3) really compares bytes rather than bits. The proof is that whatever the bit endianness is, I won't be able to detect it using memcmp(3). I'd need bitfields for that. (more) |
— | about 1 year ago |
Comment | Post #287908 |
I don't think your answer covers the part about the variable containing an invalid value (possibly a trap representation). This answer would be fine for the same question if the question didn't mention reading from an uninitialized variable (which was the main point I was interested in). (more) |
— | about 1 year ago |
Comment | Post #287760 |
If instead of a `struct` containing an array, it would be a `struct` containing many fields (e.g., `struct s2 {int a; int b; int c; int d;};`), would it change your answer in any sense? Let's say I do `struct s2 *s2 = malloc(offsetof(struct s2, c));`, and later I only use fields `a` and `b`. Would ... (more) |
— | over 1 year ago |