In C or C ++, should you check for pointer parameters to NULL / nullptr?

This question was inspired by this answer .

I have always adhered to the philosophy that the caller is not responsible when the caller does something stupid, such as passing invalid parameters. I came to this conclusion for several reasons, but perhaps the most important of them is in this article :

Everything that is not defined is undefined.

If a function does not say in it that it is valid for passing nullptr , then you damn better not to skip nullptr to that function. I do not believe that responsibility for this causes liability.

However, I know that there will be those who disagree with me. I am curious if I need to check these things and why.

+36
c ++ c null
Dec 08 2018-10-12
source share
20 answers

In general, I do not see the value when NULL is detected (why NULL, and not some other invalid address?) For the public API, I would probably still do this simply because many C and C ++ programmers expect such behavior.

+14
Dec 08 '10 at 17:08
source share

If you intend to check for NULL pointer arguments in which you have not signed up to accept and interpret them, do this with assert , rather than returning a conditional error. Thus, errors in the caller will be immediately detected and can be fixed, which makes it easy to disable the overhead in production assemblies. I ask for the value of assert , with the exception of the documentation; segfault from dereferencing a NULL pointer is just as effective for debugging.

If you return an error code to a caller who already has a proven buggy , the most likely result is that the caller will ignore the error and bad things will happen much later when the original cause of the error became difficult or impossible to track. Why is it reasonable to assume that the caller will ignore the error you are returning? Because the caller already ignored the error return malloc or fopen or some other library allocation function that returned NULL to indicate an error!

+42
Dec 08 '10 at 17:08
source share

In C ++, if you do not want to accept NULL pointers, then do not use this chance : accept the link instead.

+28
Dec 08 '10 at 16:59
source share

The depth protection principle says yes. If this is an external API, then this is absolutely necessary. Otherwise, at least approve to help debug the misuse of your API.

You can document the contract until you are blue in the face, but you cannot provide a warning code to warn you of an unnamed or malicious misuse of your function. The decision you must make is the likely cost of misuse.

+8
Dec 08 '10 at 16:51
source share

In my opinion, this is not a question of responsibility. This is a matter of reliability.

If I do not have full control over the caller, and I must optimize it even for a minute speed improvement, I always check for NULL.

+6
Dec 08 '10 at 16:53
source share

My philosophy is this: your users should be allowed to make mistakes, your development team should not.

This means that the only place you should check for invalid parameters, including NULL, is in the top-level user interface. Everywhere, when the user can enter your code, you should check for errors and handle them as gracefully as possible.

Anywhere, you should use ASSERTS to ensure that programmers use functions correctly.

If you are writing an API, then only top-level functions should catch and handle bad input. It makes no sense to constantly check the NULL pointer at three or four levels in your call stack.

+4
Dec 08 '10 at 20:52
source share

I rely heavily on the “do not trust your user, so as not to blow up your system” side in defensive programming in general. Since I made APIs in a past life, I saw library users skip null pointers and then crash applications.

If this is really an internal library, and I am the only person (or only a few select ones) who can use it, then I can simplify the verification of null pointers if everyone agrees to comply with general contracts, I can not trust the user database as a whole to stick to this.

+3
Dec 08 2018-10-12
source share

The answer will be different for C and C ++.

C ++ has links. The only difference between passing a pointer and passing a link is that the pointer can be null. So, if the writer of the called function expects a pointer argument and forgets to do something when it is zero, is he stupid, crazy or writes with C-classes.

In any case, it is not a question of who wears a hat of responsibility. In order to write good software, both programmers must work together, and all programmers are required to avoid special cases requiring such a solution, and 2 ° if this fails, write code that explodes in an unambiguous and documented way to help in debugging.

So, of course, you can point and laugh at the caller, because he messed up, and "all that is not defined is undefined", and you had to spend one hour debugging a simple error with a null pointer, but your team spent a lot of time on what .

+3
Dec 08 '10 at
source share

I am engaged in defensive programming.

If you cannot profile that these nullptr checks occur in the bottleneck of your application ... (in such cases, it is possible that these pointer value tests do not need to be done at these points)

but overall comparing int to 0 really cheap . I find it embarrassing to allow potential crashes rather than consume so little CPU.

like this: Check your pointers for NULL!

+3
Dec 08 2018-10-12
source share

I think you should strive to write code that is reliable for any conceivable situation. Passing a NULL pointer to a function is very common; therefore, your code should check it and process it, as a rule, by returning the error value. Library functions should NOT crash the application.

+1
Dec 08 2018-10-12
source share

For C ++, if your function does not accept nullpointer, use a reference argument. Generally.

There are some exceptions. For example, many people, including myself, consider this better with a pointer argument, when the actual argument will naturally be a pointer, especially when a function stores a copy of a copy of the pointer. Even if the function does not support the nullpointer argument.

How much is protected from invalid arguments, including that it depends on the subjective opinion and feelings of the gut.

Cheers and hth.,

+1
Dec 08 '10 at
source share

One thing you should consider is what happens if any caller abuses your API. In the case of passing NULL pointers, the result is an obvious failure, so it should not be checked. Any misuse will be apparent to the call code developer.

The shameful glibc error is another. Misuse has led to really useful behavior for the caller, and the API has remained that way for decades. Then they changed it.

In this case, API developers must validate values ​​using an affirmative or similar mechanism. But you cannot return in time to correct the mistake. Crying and gnashing of teeth were inevitable. Read all about it here .

+1
Dec 08 2018-10-12
source share

If you do not want NULL, then do not specify a parameter pointer.
By using the link, you guarantee that the object will not be NULL.

+1
Dec 08 '10 at 20:38
source share

I don’t think that it’s responsible for handling such things.

If he does not accept this responsibility, he can create bad results, for example dereferencing NULL pointers. The problem is that she always implicitly assumes this responsibility. That is why I prefer graceful handling.

0
Dec 08 '10 at 16:53
source share

In my opinion, it is the responsibility to comply with his contract.

If the called user should not accept NULL , then it should assert that.

Otherwise, the caller should behave well when it passes NULL . That is, either it should functionally be a non-operator, return an error code or allocate its own memory, depending on the contract that you specified for it. He should do what seems most reasonable from the perspective of the caller.

As an API user, I want to be able to continue using it without crashing the program; I want to somehow recover, or in the worst case stop.

0
Dec 08 '10 at 18:13
source share

Yes, you should check for null pointers. You do not want to crash the application because the developer messed up something.

0
Dec 08 2018-10-12T00:
source share

Anyone who performs invalid operations on invalid or non-existent data deserves to have his system state become invalid.

I find it completely pointless that functions awaiting input should check for NULL. Or something else in this regard. The sole task of a function is to perform a task based on its input or scope, nothing else. If you do not have valid input or no input at all, then do not even call the function. In addition, NULL-check does not detect other millions and millions of possible invalid values. You know that at forehand you would have missed NULL, so why would you still pass it, spend valuable cycles on another function call with parameter passing, compare functions with some functions, and then check the function output again for success or not, Of course, I could do this when I was 6 years ago in 1982, but these days have long since disappeared.

There is, of course, an argument to be made for public APIs. Like some dlls that offer idiot checking. You know these arguments: "If the user supplies NULL, you do not want your application to crash." Which is not an argument. This is the user who primarily transfers the dummy data; it is a clear choice and nothing else. If you feel that this is quality, well ... I prefer solid logic and performance over such things. In addition, the programmer must know what he is doing. If he works with invalid data for a specific area, then he does not have a business calling himself a programmer. I see no reason to reduce performance, increase power consumption, increasing the size of binary files, which, in turn, affects command caching and branch prediction of my products in order to support such users.

0
Feb 19 '15 at 11:52
source share

In this case, there is a difference between what I would call legal and moral responsibility. Suppose you see a visually impaired person walking towards the edge of a cliff, blithely unaware of his existence. As for your legal liability, in general, you will not be able to successfully prosecute you if you do not warn him, and he continues to walk, falls from a cliff and dies. On the other hand, you had the opportunity to warn him - you were able to save your life, and you consciously decided not to do it. The average person is inclined to consider such behavior with contempt, judging that you had a moral responsibility to do the right thing.

How does this relate to this issue? Simple - the called party does not bear "legal responsibility" for the actions of the caller, silly or otherwise, for example, skips invalid input. On the other hand, when things go up, and it is observed that a simple check inside your function could save the caller from his own stupidity, you end up sharing moral responsibility for what happened.

Of course, there is a trade-off, depending on how much the check really costs you. Returning to the analogy, suppose that you learned that the same stranger is slowly approaching a rock on the other side of the world, and that by spending your life and warning him, you can save him. Very few people will judge you very harshly if you neglect this in this particular situation (suppose the phone was not invented for the purposes of this analogy). However, under coding conditions, if checking is as simple as checking for NULL , you shy away from doing it, even if the "real" one is to blame for the situation with the caller.

-one
Dec 08 '10 at 18:18
source share

One of the side effects of this approach is that when your library crashes in response to passing an invalid argument, you will usually get the blame.

There is no better example of this than the Windows operating system. Microsoft's initial approach was to eliminate many tests for dummy arguments. The result was an operating system that was more efficient.

However, the reality is that invalid arguments are passed all the time. From programmers who are not up to tobacco, or simply using the values ​​returned by other functions, they were not expected to be NULL. Windows now does a lot of checking and is less efficient.

If you want your routines to crash, do not check for invalid parameters.

-one
Dec 08 '10 at 21:02
source share

Overhead for development time + runtime performance is in tradeoff with the robustness of the API you are developing.

If the API you publish is to be launched inside the process of the calling procedure, you SHOULD NOT check for NULL or invalid arguments. In this case, if you fail, the client program will fail, and the developer using your API must fix its path.

However, if you provide a runtime that will run the client program inside it (for example, you write a virtual machine or middleware that can host code or an operating system), you should definitely check the validity of the arguments passed. You do not want your program to depend on plugin errors.

-one
Dec 26 '10 at 9:57
source share



All Articles