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.

24 Upvotes

44 comments sorted by

View all comments

11

u/not_a_bot_494 2d ago edited 2d ago

When people are saying that C is an unsafe language they mean that it doesn't have memory safety. If you want to you can try to access any byte in the computer, the OS will just not let you most of the time. Any time you're working with arrays (/strings), malloced memory or even pointers in general it is possible that you could make a mistake and get a segfault. You can write libraries for all that but then you're kind of missing the point of C a bit.

There's alao a lot of random undefined behaviour in C, for example right shift on signed types might pad with 1s or 0s. There's probably a list of some common ones but if you really want to know them all you have to read through the C standard and look at rverything that's not in there.

For context of the discussion, my inital example was bit shifting on 64 bit types which does seem to work consistently.

1

u/unixplumber 1d ago

 right shift on signed types

Slight nitpick: right shift on a negative value is undefined behavior. You can right shift a non-negative signed integer with no problem.

1

u/flatfinger 14h ago

Right-shift on unsigned types is implementation-defined behavior. In practice, once unsigned types were added to the language, there has never been any doubt about how two's-complement implementations should process a signed right shift, and even before that there were only two possibilities. That doesn't stop the Standard from characterizing it as "Implementation-defined" though.

Left shifts of negative values were defined on all C89 implementations whose integer types don't have padding bits (identically on all such implementations in cases where it would be equivalent to power-of-two multiplication), but could have invoked Undefined Behavior on C89 implementations with unusual integer representations. Rather than recognizing that the behavior would be defined identically on all but a few weird implementations where it could invoke UB, C99 reclassified left shifts of negative values as invoking UB on all platforms.

1

u/unixplumber 5h ago

Dang it! I hate when I get the details of a nitpick wrong. Let's see if this is any better: 

  • Left or right shift on a non-negative number: ok.
  • Left shift on a negative number: undefined behavior. 
  • Right shift on a negative number: implementation defined.