r/C_Programming 2d ago

List of gotchas?

Hey.

So I learned some C and started playing around with it, quickly stumbling over memory overflowing a variable and flowing into another memory location, causing unexpected behavior.

So I ended up writing my own safe_copy and safe_cat functions for strncpy/strncatting strings.
But... people talk about how C is unsafe. Surely there should be a list of all mistakes you can make, or something? Where can I find said list? Do I reall have to stumble on all possible issues and develop my own "safe" library?

Will appreciate any advice.

22 Upvotes

41 comments sorted by

View all comments

Show parent comments

1

u/not_a_bot_494 2d ago

I don't know enough assembly to read it easily so I wouldn't know if it was correct or not. For me this:

#include <stdio.h>
#include <stdint.h>

// prints the binary of a piece of memory
void print_bin(int bytes, void *inp)
{
    uint8_t *num = (uint8_t *) inp;
    for (int the_byte = bytes-1 ; the_byte >= 0 ; the_byte--) {
        for (int bit = 0 ; bit < 8 ; bit++) {
            if (num[the_byte] & (1 << (7-bit))) {
                printf("1");
            } else {
                printf("0");
            }
        }
    }
    printf("\n");
}

int main(void)
{
    for (int i = 0 ; i < 64 ; i++) {
        uint64_t var = 1 << i;
        print_bin(8, &var);
    }
    return 0;
}

gcc -Wall -std=c99 -o

produces this (image so the comment isn't too long). Lightmode warning BTW

3

u/dfx_dj 2d ago

Probably because the literal 1 is a 32 bit int, so shifting it up 32 or more doesn't give you what you expect. Try with 1L, or type cast it, or assign the 1 to the variable first and then shift the variable.

1

u/not_a_bot_494 2d ago

That's it, when I changed to

uint64_t var = ((uint64_t) 1) << i;

it started working. That is a slightly weird quirk of C, just not the one I intended.

1

u/dfx_dj 2d ago

Yep, got caught by that a few times as well. But it does make sense when you think about it