87 points by ingve 10 hours ago | 27 comments
fuhsnn 6 hours ago
[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3531.txt
cb321 5 hours ago
Add a namespacing macro and you have a whole generics system, unlike that in TFA.
So, it might add more value to have the C std add an `#include "file.c" name1=val1 name2=val2` preprocessor syntax where name1, name2 would be on a "stack" and be popped after processing the file. This would let you do types/functions/whatever "generic modules" with manual instantiation which kind of fits with C (manual management of memory, bounds checking, etc.) but preprocessor-assisted "macro scoping" for nested generics. Perhaps an idea to play with in your slimcc fork?
hyperbolablabla 3 hours ago
JonChesterfield 3 hours ago
IAmLiterallyAB 2 hours ago
waynecochran 2 hours ago
uecker 38 minutes ago
unwind 7 hours ago
glouwbug 15 minutes ago
#include <stdlib.h>
#include <stdio.h>
#define vec(T) struct vec##T { T* val; int size; int cap; }
#define vec_push(self, x) { \
if((self).size == (self).cap) { \
(self).cap = (self).cap == 0 ? 1 : 2 * (self).cap; \
(self).val = realloc((self).val, sizeof(*(self).val) * (self).cap); \
} \
(self).val[(self).size++] = x; \
}
#define vec_for(self, at, ...) \
for(int i = 0; i < (self).size; i++) { \
auto at = &(self).val[i]; \
__VA_ARGS__ \
}
struct test
{
vec(double) v;
};
void test_fun(vec(double)* self)
{
vec_push(*self, 4.0);
vec_push(*self, 5.0);
}
int main()
{
vec(int) a = {};
vec_push(a, 1);
vec_push(a, 2);
vec_push(a, 3);
vec_for(a, at, {
printf("%d\n", *at);
});
struct test test = {};
vec_push(test.v, 1.0);
vec_push(test.v, 2.0);
vec_push(test.v, 3.0);
test_fun(&test.v);
vec_for(test.v, at, {
printf("%f\n", *at);
});
}
rwmj 6 hours ago
r1chardnl 6 hours ago
Never mix unsigned and signed operands. Prefer signed. If you need to convert an operand, see (2).
https://nullprogram.com/blog/2024/05/24/poly2it 5 hours ago
You cannot even check the signedness of a signed size to detect an overflow, because signed overflow is undefined!
The remaining argument from what I can tell is that comparisons between signed and unsigned sizes are bug-prone. There is however, a dedicated warning to resolve this instantly.
It makes sense that you should be able to assign a pointer to a size. If the size is signed, this cannot be done due to its smaller capacity.
Given this, I can't understand the justification. I'm currently using unsigned sizes. If you have anything contradicting, please comment :^)
sparkie 3 hours ago
IMO, this is a better approach than using signed types for indexing, but AFAIK, it's not included in GCC/glibc or gnulib. It's an optional extension and you're supposed to define `__STDC_WANT_LIB_EXT1__` to use it.
I don't know if any compiler actually supports it. It came from Microsoft and was submitted for standardization, but ISO made some changes from Microsoft's own implementation.
https://www.open-std.org/JTC1/SC22/WG14/www/docs/n1173.pdf#p...
windward 1 hour ago
sim7c00 4 hours ago
int somearray[10];
new_ptr = somearray + signed_value;
or
element = somearray[signedvalue];
this seems almost criminal to how my brain does logic/C code.
The only thing i could think of is this:
somearray+=11; somearray[-1] // index set to somearray[10] ??
if i'd see my CPU execute that i'd want it to please stop. I'd want my compiler to shout at me like a little child, and be mean until i do better.
-Wall -Wextra -Wextra -Wpedantic <-- that should flag i think any of these weird practices.
As you stated tho, i'd be keen to learn why i am wrong!
windward 1 hour ago
Arrays aren't the best example, since they are inherently about linear, scalar offsets, but you might see a negative offset from the start of a (decayed) array in the implementation of an allocator with clobber canaries before and after the data.
ncruces 4 hours ago
Why?
By the definition of ptrdiff_t, ISTM the size of any object allocated by malloc cannot be out of bounds of ptrdiff_t, so I'm not sure how can you have a useful size_t that uses the sign bit?
foldr 4 hours ago
rurban 3 hours ago
o11c 35 minutes ago
tialaramex 6 hours ago
yorwba 6 hours ago
"struct Goose { float weight; }" and "struct Beaver { float weight; }" would remain incompatible, as would "struct { float weight; }" and "struct { float weight; }" (since they're declared without tags.)
tialaramex 6 hours ago
Surac 6 hours ago
poly2it 5 hours ago
pests 1 hour ago
ioasuncvinvaer 6 hours ago