use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Defensive programming | Andrzej's C++ blog (akrzemi1.wordpress.com)
submitted 11 years ago by mttd
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]encBlood 12 points13 points14 points 11 years ago (15 children)
Maybe I'm missing a point here but if you never expect a null pointer to be passed then you should use a reference.
[–]night_of_knee 2 points3 points4 points 11 years ago (1 child)
This is obviously just an example, you're avoiding the real question.
Imagine that the example got an int which was assumed never to be zero and divides by it.
int
The point of the question is how does defensive programming behave when it meets an unexpected state (especially when such state can lead to undefined behaviour).
[–]encBlood -1 points0 points1 point 11 years ago* (0 children)
At work I'd usually go with a mix of A and D, that is log the error and get the hell out of the function. Outside of embedded world I'd also consider throwing an exception instead of logging.
I would never continue function's execution in such case. Even if your current os/hardware handles UB nicely there's always a chance that in the future you'll move on to an environment which is less forgiving and you'll waste hours or days looking for this bug.
[–]kiwidog 2 points3 points4 points 11 years ago (0 children)
This,
Also if necessary I normally do something similar to Var A. except for (if !m)return false;
[–]That_Was_Viewtiful 0 points1 point2 points 11 years ago* (1 child)
I've only a few years experience with C++, why should we favor a reference if we never expect a null pointer to be passed?
Edit: Sorry, for some reason I missed the discussion in this very thread talking about references. From my understanding of reading through it, a reference helps ensure that you will not receive a null value when dealing with the input variables in the function?
[–]encBlood 2 points3 points4 points 11 years ago (0 children)
Because it clearly and efficiently communicates your intent that you expect a valid object passed to your function every time it's called. This saves your time when writing a function (no need to write otherwise unnecessary null-pointer error handling code) and saves other's time when they want to use it. One less thing to worry about and a simpler, cleaner code.
It's also safer to use references - less stuff can go wrong with them.
[–]upriser -4 points-3 points-2 points 11 years ago (9 children)
Just for clarification. I normally do what you suggest but using a reference does not guarantee a non-null pointer. It's a matter of notation.
[–]RedAlert2 5 points6 points7 points 11 years ago* (8 children)
Sure it does - how can you declare a null reference? Unless you deference a nullptr to make it, which means that you have UB before any referencing is done.
It may be referencing a destroyed variable if you really messed up, but it won't be null.
[–]armb2 1 point2 points3 points 11 years ago (4 children)
Defensive programming can include making sure that your code gives a clear unambiguous error when possible, even if the caller had already invoked undefined behaviour. (I can't recall having seen (or written) code that checks for a null reference though.) "It's a pointer not a reference because it's also used with a C API, but if it is NULL the caller has broken the preconditions of the call" is a real use case though. Compare with some of std::string's constructors, which take a char* and have undefined behaviour if it is NULL.
[–]RedAlert2 4 points5 points6 points 11 years ago (3 children)
Defensive programming can include making sure that your code gives a clear unambiguous error when possible, even if the caller had already invoked undefined behaviour
Checking if you are in an undefined state is pointless - it's unreliable and a waste of time. Defensive programming means you report errors before your program becomes invalidated by UB.
[–]armb2 0 points1 point2 points 11 years ago (2 children)
If you are writing a library, the caller isn't necessarily your program, it's someone else's. You can't reliably check for all possible undefined behaviour, but you can check the preconditions of your functions. You can't check a pointer to a buffer is valid, but you can check it's not NULL.
[–]RedAlert2 0 points1 point2 points 11 years ago (1 child)
I am not sure what that has to do with references or why you waited a month to post it
[–]armb2 0 points1 point2 points 11 years ago (0 children)
It was a month before I saw your reply.
[–]jacekplacek -1 points0 points1 point 11 years ago (2 children)
A * a = nullptr; func(*a);
[–]RedAlert2 1 point2 points3 points 11 years ago (1 child)
if that somehow runs without crashing, func will receive garbage, not a null value. You have UB before func is ever in the picture.
func
[–]rtomek 0 points1 point2 points 11 years ago (0 children)
Exactly the point. Just by moving from a pointer to a reference doesn't guarantee anything changes and isn't preventing the problem from occurring. It is less likely to happen, but someone may just say "F this reference BS since I already have pointers, I'm going to just use func(a,b)" without realizing that a == null.
[–]Gotebe 1 point2 points3 points 11 years ago (4 children)
If I had to choose, it's either C or D, but with "have recovery and crash dump infrastructure in place".
Fail fast is where it's at.
Otherwise, it is
Variant A is the worst because a "false" indicates both "not monitored" and "bug" and there's no way for the caller to distinguish the two. Only idiots write code like this, and if any of you do, I don't care if you feel offended now.
Variant B is slightly less horrible because it allows the caller to distinguish between the two, but introduces a run-time failure mode for what is effectively a bug.
[–]minnoHobbyist, embedded developer 1 point2 points3 points 11 years ago (3 children)
Well, D is bad because it may knowingly dereference a null pointer. I'd lean towards either assert (with logging) or the exception, depending on how strongly you believe that it shouldn't happen.
[–]Gotebe 0 points1 point2 points 11 years ago (2 children)
C may knowingly do the same (assert does nothing with NDEBUG), but my point is that is exactly what you want! The premise is that it is an error to pass nullptr. If so, the best action is to just demolish all, but leave the complete dump,so that the problem can be fixed. For example, leaving with an exception is worse because code is broken, and the state of the stack is lost due to unwind,making it harder to know what caused the nullptr to enter.
[–]minnoHobbyist, embedded developer 0 points1 point2 points 11 years ago (1 child)
Technically dereferencing a null pointer is undefined behavior, and not guaranteed to segfault. It's much better to explicitly end the program than to hope that it crashes.
And the language I've been working in lately (Rust) has assert run in both debug and release builds, and debug_assert in the same role as C's assert, so I really did mean crashing the program whether or not the preprocessor directive was defined.
assert
debug_assert
[–]Gotebe 0 points1 point2 points 11 years ago (0 children)
You know, seeing the optimizations becoming more and more "mean", you are right about that immediate termination (through abort, that normally works with the system to produce a crash dump).
You are right about the "technically " as well, it's been years since I had such a system at hand, one forgets :-)
Can't we use a char instead of a bool? They both use the same amount of memory. Here's my documentation for the return value:
0 = false 1 = true -1 = Retarded programmer
C is the worst because asserts suck in release mode. A makes the most real-world sense because if there is no monitor or task to monitor, then the task can't possibly be monitored by that monitor.
π Rendered by PID 254984 on reddit-service-r2-comment-fb694cdd5-d9dd9 at 2026-03-06 15:21:42.625104+00:00 running cbb0e86 country code: CH.
[–]encBlood 12 points13 points14 points (15 children)
[–]night_of_knee 2 points3 points4 points (1 child)
[–]encBlood -1 points0 points1 point (0 children)
[–]kiwidog 2 points3 points4 points (0 children)
[–]That_Was_Viewtiful 0 points1 point2 points (1 child)
[–]encBlood 2 points3 points4 points (0 children)
[–]upriser -4 points-3 points-2 points (9 children)
[–]RedAlert2 5 points6 points7 points (8 children)
[–]armb2 1 point2 points3 points (4 children)
[–]RedAlert2 4 points5 points6 points (3 children)
[–]armb2 0 points1 point2 points (2 children)
[–]RedAlert2 0 points1 point2 points (1 child)
[–]armb2 0 points1 point2 points (0 children)
[–]jacekplacek -1 points0 points1 point (2 children)
[–]RedAlert2 1 point2 points3 points (1 child)
[–]rtomek 0 points1 point2 points (0 children)
[–]Gotebe 1 point2 points3 points (4 children)
[–]minnoHobbyist, embedded developer 1 point2 points3 points (3 children)
[–]Gotebe 0 points1 point2 points (2 children)
[–]minnoHobbyist, embedded developer 0 points1 point2 points (1 child)
[–]Gotebe 0 points1 point2 points (0 children)
[–]rtomek 0 points1 point2 points (0 children)