Update (2020-08-07): This is a republish of my second blog post, dated 2005-04-20: ASSERT!!, ASSERT!!, ASSERT!!. Devblog only lets me backdate this to 2015.
To me, putting assertions in my code is one of the most useful things I can do when writing code. I have tried to get in the habit of noticing any assumption I'm making, and then putting that in my code as some form of an assert().
For example, if I were to cast a pointer to a long, I would make sure that it would fit (since C does not guarantee that). And, for something like this, you can make it a compile-time assertion that doesn't cost any run-time. Within C code, this can be done with
assert(sizeof(long) >= sizeof(ptr)). As another example, if your code does a
while (--num > 0), it wouldn't be a bad idea to use an
assert(num != 0) if
num is unsigned.
I also rely on assertions as a way to efficiently write new code. If I'm doing socket programing, for example, I may just write
assert(socket(...) >= 0). This way, I can quickly write my code without worrying yet about providing good feedback to users (i.e. error messages), yet also avoid the confusing bug that may occur when a file descriptor with the value -1 is written to. Plus, I can easily search for "assert(" later if I feel like giving useful error messages to users.
Assertions also provide me a benefit when I'm programming. When I see an assertion, I can know that the given condition is true. This allows me to reduce the problem space because I may know, for example, that I given pointer is never NULL.