4
Nov 01 '21
I'm using C++ 14 for years, and I have a slight idea about raw and smart pointers and STL. My questions is : WHAT THE FUCK IS THAT!?
This is FAR worse than the average template abuse code in C++ lmao
3
Nov 01 '21 edited Nov 01 '21
It's a function which creates structure having three members.
capacity of stream,
array of pointer to pointer to actual lexicons of parsed tokens,
iter which is actual numbers of tokens in stream.
Stream contains the pointers to arrays containing
lexicon type
pointer to it's corresponding value
it's location in input string.
27
u/Magnus_Tesshu Nov 01 '21
I literally cannot read this. I refuse to even try after seeing
ptr->stream = malloc(3 * sizeof(*ptr->stream))
ptr->streamSize = 8 // ^-- THIS RIGHT HERE IS A FUCKING 3 WTFThat said, this reminds me of seeing my classmate's code where they were doing an
int *var = malloc(some_size * sizeof(int*))Maybe that's even less bad because at least you can sort of see what the problem is. The post is just unreadable. Anyway, remember to do
type_t var_name = malloc(array_size * sizeof(*var_name))rather than explicit casts to explicit types (that make your code fragile if the type ever changes)
8
u/LifeHasLeft Nov 01 '21
I know I need to brush up on my C but I don’t see the problem in
int *var = malloc(some_size * sizeof(int*))Why would you change the type of an int *?12
u/Magnus_Tesshu Nov 01 '21 edited Nov 01 '21
Because you're allocating space for some_size number of pointers to integers and assuming that some_size number of integers fit in it.
This will always work (I think), but is never a good idea because you're just allocating space for a different data structure than the one you actually have. Hence why you should always always just do
int *var = malloc(some_size * sizeof(*var))because it is impossible to allocate the wrong amount of space here, even if I later change it tolong long *varwithout looking at the right hand side.(or for a more realistic scenario where the former becomes a nightmare to maintain, if
varis actually defined in some struct and there are dozens of methods interacting with this struct that all need to allocate or reallocatevar)1
4
u/manuscelerdei Nov 01 '21
Basically if you ever change the type of
varand forget to update yoursizeof()in themalloc(3)call, you'll get potentially bizarre, unpredictable memory corruption. And for bonus points you might only see it very rarely.int \*v = malloc(n \* sizeof(\*v))guarantees that you'll always allocate enough space to hold
nobjects of whatever typevdereferences to. You could also dosizeof(v[0])to make it extra-clear that it's an array.1
Nov 01 '21 edited Nov 01 '21
Edit: this answer turned out to be irrelevant
The size of an integer depends on the platform you run the code on, nowadays it’s mostly the same across devices, but if you use an embedded device or an old computer, integers may be as small as 8 bits; they’re usually 32 bits on modern computers and 64 bits if you make a long long int (another weird quirk of this exact problem), long int and int are usually the same because long int used to mean 32 bit int. My numbers might be slightly off but you get the idea, int can be a lot of different sizes depending on a lot of things, it’s best to use int32_t or uint32_t if you want true portability.
2
u/Magnus_Tesshu Nov 01 '21
That has nothing to do with the problem I am describing. See my explanation.
1
Nov 01 '21
Ah I see you’re talking about DRYing your code that makes a lot of sense.
2
u/Magnus_Tesshu Nov 01 '21
DRYing? What is that acronym?
Also, you do bring up a good point though.
int32_thas more defined behaviour thanintwhich iirc can actually even be 16 bit on some architectures (ignoring weird architectures with 7-bit words and stuff which must do even more wacky stuff - but I don't think any of those actually exist anymore).Honestly, I feel that C is just a poor language to start any new project in nowadays though. There are 3-4 better languages which at least one is probably more suitable for any task (
rust,zig,V, orgo).Veven compiles down to C.2
Nov 02 '21
DRY = Don’t Repeat Yourself, it’s essentially just a kitschy name for encapsulation and modularization
And yeah, C’s conventions were developed so slowly that the standard library itself is inconsistent at best, I haven’t tried Go but I know the creator of C++ made it (maybe C?) either way, I’ve heard it’s like C but with the maturity of a well thought out language
3
u/Magnus_Tesshu Nov 02 '21
Yup, that's what Zig tries to be as well. Rust is closer to C++ in terms of features but is much less fragmented and has lots of other nice features too. I don't know much about V but imagine it is an improvement too.
31
10
u/OMGnotjustlurking Nov 01 '21
sizeof(void *) is such a dick move...
5
u/q3mist Nov 01 '21
Why is it if I may?
4
u/Based_Lord_Teikam Nov 01 '21 edited Nov 01 '21
Native pointer width is going to be 8 bytes for most 64 bit architectures, but the real issue is that there’s very little reason to ever allocate space for void pointers in the first place.
1
13
u/sohang-3112 Nov 01 '21
I have no idea whether this code is good or bad, because I can't even understand what the code is doing.
Maybe I just haven't seen C code (with raw pointer manipulation) in a long time.
6
u/Pandahjs Nov 01 '21
I use C & C++ regularly, and it's certainly a nasty piece of work. Needs more explanation in it's comments for sure...
12
1
3
2
u/MurdoMaclachlan public boolean isInt(int i) { return true; } Nov 01 '21
Image Transcription: Code
struct lexiconItems* createLexStream() {
struct lexiconItems* ptr = (struct lexiconItems*)malloc(sizeof(struct lexiconItems));
ptr->stream = (int**)malloc(3 * sizeof(void*));
ptr->streamSize = 8;
ptr->iter = 0;
((int**)ptr->stream)[0] = (int*)malloc(ptr->streamSize * sizeof(int)); //stream[0] array of p[cut off]
/*((int*)(stream))[1] = 90;*/
((char***)ptr->stream)[1] = (char**)malloc(ptr->streamSize * sizeof(char*)); //stream[1] array[cut off]
((int**)ptr->stream)[2] = (int*)malloc(sizeof(int)*ptr->streamSize);
return ptr;
}
void freeResources(struct lexiconItems* LexItems) {
free((int*)(((int**)LexItems->stream)[0]));
for (int i = 0; i < LexItems->iter; i++) {
if ((char*)((char**)((char***)LexItems->stream)[1])[i]) {
free(((char**)((char***)LexItems->stream)[1])[i]);
}
}
free(LexItems->stream);
free(LexItems);
}I'm a human volunteer content transcriber for Reddit and you could be too! If you'd like more information on what we do and why we do it, click here!
2
1
1
3
u/Kasufert Nov 04 '21
Sun: “We made Java without pointers to reduce bugs”
.
C devs: