You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.

  1. With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):

    SomeResource* SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return &(*it);  
        return NULL;  
    }
    
  2. Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):

    std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return std::make_pair(*it, true);  
        return std::make_pair(SomeResource(), false);  
    }
    
  3. Using boost::optional:

    boost::optional<SomeResource> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return *it;  
        return boost::optional<SomeResource>();  
    }
    

If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.

I also modified your example so you're not searching the map twice (by reusing the iterator).

Answer from Sven on Stack Overflow
Top answer
1 of 10
57

You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.

  1. With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):

    SomeResource* SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return &(*it);  
        return NULL;  
    }
    
  2. Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):

    std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return std::make_pair(*it, true);  
        return std::make_pair(SomeResource(), false);  
    }
    
  3. Using boost::optional:

    boost::optional<SomeResource> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return *it;  
        return boost::optional<SomeResource>();  
    }
    

If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.

I also modified your example so you're not searching the map twice (by reusing the iterator).

2 of 10
31

Why "besides using pointers"? Using pointers is the way you do it in C++. Unless you define some "optional" type which has something like the isNull() function you mentioned. (or use an existing one, like boost::optional)

References are designed, and guaranteed, to never be null. Asking "so how do I make them null" is nonsensical. You use pointers when you need a "nullable reference".

🌐
Quora
quora.com › How-do-you-return-a-null-pointer-in-C
How to return a null pointer in C - Quora
Answer (1 of 7): “How do you return a null pointer in C?” This will do it: [code]return (void*)0; [/code]Enjoy your null pointer!
Discussions

Returning reference of NULL pointer
nullptr is a pointer, why do you want to return the adress of it? More on reddit.com
🌐 r/cpp_questions
16
1
July 18, 2021
pointers - Why is there no "NULL reference" in C++? - Stack Overflow
Use references when you can, and pointers when you have to. ... The exception to the above is where a function's parameter or return value needs a "sentinel" reference — a reference that does not refer to an object. This is usually best done by returning/taking a pointer, and giving the NULL ... More on stackoverflow.com
🌐 stackoverflow.com
Assigning return value of a function to - C++ Forum
If the function returns a non-const ... Reference initialisation: http://en.cppreference.com/w/cpp/language/reference_initialization ... And what would be the value of the ref variable, if the function returns null?... More on cplusplus.com
🌐 cplusplus.com
What does it mean to do a "null check" in C or C++? - Software Engineering Stack Exchange
My favorite technique when it comes to object pointers is to use the Null Object pattern. That means returning a (pointer - or even better, reference to an) empty array or list instead of null, or returning an empty string ("") instead of null, or even the string "0" (or something equivalent ... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
🌐
Bytes
bytes.com › home › forum › topic
Function returning a "null" reference object - Post.Byes
August 19, 2005 - You can return a boost::shared_p tr or something like that and check if it has a valid pointer inside. IIRC it goes exactly like with a normal pointer. -- Attila aka WW ... Re: Function returning a &quot;null&quot ; reference object "Pablo J Royo" <royop@tb-solutions.com> wrote in message news:<HqUbb.516 $Hd.297012@news-reader.eresmas.
🌐
Quora
quora.com › Is-it-legal-in-C-C-to-return-NULL
Is it legal in C/C++ to 'return NULL'? - Quora
Answer (1 of 21): There is no such thing like “C/C++”. return NULL is legal in C and it usually means, by convention, that something went wrong, e.g. an allocation, and the calling context is supposed to handle the error. In C++, while return nullptr would be legal and well-defined too, ...
🌐
Reddit
reddit.com › r/cpp_questions › returning reference of null pointer
r/cpp_questions on Reddit: Returning reference of NULL pointer
July 18, 2021 -

In following function I'm trying find a node in Binary tree that matches the key. I'm passing reference node pointer as smart pointer and this function returns a refernce to node pointer.

How can I return NULL ? As the return value of function is std::unique_ptr<node>& so it is supposed to return a reference.

std::unique_ptr<node>& BST::ReturnNodePrivate(const int& key, std::unique_ptr<node> &ptr){
    if(NULL != ptr){
        if(ptr->key == key){
            return ptr;
         } 
    } 
     else{ 
        return NULL; 
     } 
}

How can I return NULL ?

Top answer
1 of 5
15

Because a reference carries the semantic that it points to a valid memory address that never changes; i.e. that dereferencing it is safe/defined and so no NULL checks are required. References cannot be reassigned by design.

You use a pointer when the var can be NULL and client code has to handle that case. You use a reference when you can guarantee a valid/initialised memory address.

One example of using pointers is as a member of a class to store a "reference" to some instance that might not be known or able to be initialised at class construction time. However, member references must be initialised at construction time (via initialiser lists) and their assignment cannot be deferred.

If you allow a null reference it is then no different to a pointer besides syntax (the same NULL checks would need to take place.)

Update:

"And, in most OOP languages, objects can be NULL - Pascal, C#, Java, JavaScript, PHP, etc. [...] So why is C++ somehow special and doesn't have a NULL object? Was it just an overlook or an actual decision?"

I think you are a bit confused about this. Java and C# etc. might give the impression of "NULL objects", but these object references are more or less like a C++ pointer with simpler syntax, GC instrumentation and exception throwing. In those languages if you operate on a "Null Object" you will get some kind of exception like NullReferenceException (C#). Hell, in Java its called a NullPointerException.

You have to check for null before you can use them safely. Kind of like C++ pointers (except in most managed languages, pointers are initialised to NULL by default, whereas in C++ its usually up to you to take care of setting the initial pointer value (otherwise undefined/whatever memory was already there)).

The C++ view is about having choice, and hence being verbose:

  • Use a plain pointer to do how you please, checking NULL where necessary.
  • Use references which have a compiler-enforced validity semantic/constraint.
  • Roll your own smart pointers that do bookkeeping and behave whichever way you want them to.
  • Using void pointers (cautiously!) to reference an untyped block of memory if ever required.
2 of 5
6

Please have a look at differences between pointers and references - while the standard leaves it open how references are implemented, they are at the moment always implemented as pointers.

Which means that the main difference between them is a) semantics b) pointers can be reseated c) pointers can be null.

So the short answer is, this was done on purpose. When you as programmer see a reference you should know that a) that reference is populated b) it won't change (and c) you can use it with the same semantics as an object).

Would the standard allow a null reference, you would always have to check for null before using a reference, which was not wanted.

Edit:

Regarding your edit, I guess the confusion here might stem from the fact that most simpler OO languages hide what is going on. To take Java as example, while it looks like you have NULL objects, and can assign them, you really can't - what is really going on is that Java only has pointers, and can assign null values to those pointers. Since it is impossible to actually have objects directly in Java, they do away with pointer semantics and treat the pointer as the object. C++ is simply more powerful - and error prone (Java enthusiast would say that stack user class instances are not required, and the decision to not have them in Java was driven to reduce complexity, and make Java easier to use). It also follows that, since Java doesn't have objects, it doesn't have references. What really doesn't help, though, is that Java calls what a C++ person would call a pass-by-value of a pointer a pass-by-reference.

🌐
Cplusplus
cplusplus.com › forum › general › 171348
Assigning return value of a function to - C++ Forum
What does 'null' mean in this context? If the function returns void, we can't use references at all; void is not an object-type. void foo() ; const auto& v = foo() ; // *** error: cannot form a reference to 'void' If the function returns a pointer, we can initialise a references with it; a pointer is an object-type.
Find elsewhere
Top answer
1 of 6
30

In C and C++, pointers are inherently unsafe, that is, when you dereference a pointer, it is your own responsibility to make sure it points somewhere valid; this is part of what "manual memory management" is about (as opposed to the automatic memory management schemes implemented in languages like Java, PHP, or the .NET runtime, which won't allow you to create invalid references without considerable effort).

A common solution that catches many errors is to set all pointers that don't point to anything as NULL (or, in correct C++, 0), and checking for that before accessing the pointer. Specifically, it is common practice to initialize all pointers to NULL (unless you already have something to point them at when you declare them), and set them to NULL when you delete or free() them (unless they go out of scope immediately after that). Example (in C, but also valid C++):

void fill_foo(int* foo) {
    *foo = 23; // this will crash and burn if foo is NULL
}

A better version:

void fill_foo(int* foo) {
    if (!foo) { // this is the NULL check
        printf("This is wrong\n");
        return;
    }
    *foo = 23;
}

Without the null check, passing a NULL pointer into this function will cause a segfault, and there is nothing you can do - the OS will simply kill your process and maybe core-dump or pop up a crash report dialog. With the null check in place, you can perform proper error handling and recover gracefully - correct the problem yourself, abort the current operation, write a log entry, notify the user, whatever is appropriate.

2 of 6
8

The other answers pretty much covered your exact question. A null check is made to be sure that the pointer you received actually points to a valid instance of a type (objects, primitives, etc).

I'm going to add my own piece of advice here, though. Avoid null checks. :) Null checks (and other forms of Defensive Programming) clutter code up, and actually make it more error prone than other error-handling techniques.

My favorite technique when it comes to object pointers is to use the Null Object pattern. That means returning a (pointer - or even better, reference to an) empty array or list instead of null, or returning an empty string ("") instead of null, or even the string "0" (or something equivalent to "nothing" in the context) where you expect it to be parsed to an integer.

As a bonus, here's a little something you might not have known about the null pointer, which was (first formally) implemented by C.A.R. Hoare for the Algol W language in 1965.

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.

🌐
Reddit
reddit.com › r/c_programming › can you return null from a function that returns a multidimensional ***pointer?
r/C_Programming on Reddit: Can you return NULL from a function that returns a multidimensional ***pointer?
January 17, 2022 -

I am very sure that someone told me once that NULL is defined as a pointer to void. I leafed through the K&R, and NULL was just said to be interchangeable with zero.

But either way, if I have a function that returns a 3d char array (array of arrays of strings), can I then return NULL if something goes wrong? will it be a valid return type?

Many functions that return pointers return NULL if something goes wrong - fopen for instance where you check for NULL and then perror.

But I am confused about multi-dimensional pointers.

I mean, I know that they are technically just pointers. I am unsure what the multiple asterisks do except tell the programmer how many dimensions there are. Hmmm Is this the solution?

Comments?

🌐
W3Schools
w3schools.com › c › c_null.php
C NULL
You can compare a pointer to NULL to check if it is safe to use. Many C functions return NULL when something goes wrong. For example, fopen() returns NULL if a file cannot be opened, and malloc() returns NULL if memory allocation fails.
🌐
GitHub
github.com › dotnet › csharplang › issues › 1201
Ref returns can't easily return null · Issue #1201 · dotnet/csharplang
Attempting to return null generates ... return needs to return a null value, you can either return a null (uninstantiated) value for a reference type or a nullable type for a value type."...
Author: dotnet
🌐
Quora
quora.com › Can-you-return-null-in-C
Can you return null in C++? - Quora
Answer (1 of 10): If you are interfacing with C and dealing with pointers you can return a pointer to an object. That pointer can be NULL, if the function fails or actually succeeds but returns a null value. Because NULL is universally represented as a pointer to address [code ]0x00000000[/code]...
🌐
Medium
medium.com › @dcook_net › to-null-or-not-to-null-304571effc80
To Null, or not to Null?!?. I’ll start this post with a question: | by Dave Cook | Medium
December 5, 2019 - It’s not a quick fix though; opting for these settings on even a small project may suddenly create quite a bit of work in order to get it compiling again. So what do we get for our efforts? How do non-nullable reference types address the 3 problems discussed above? Returning null forces work on to our consumer: The compiler is now preventing us from returning null at design time, so that solves that issue.
🌐
Reddit
reddit.com › r/cpp › no, references are never null.
r/cpp on Reddit: No, references are never null.
March 1, 2018 -

I just have to get this rant off my chest, since I've received a few comments about it on both my blog and an associated Reddit post.

Maybe I'm preaching to the choir. Maybe I'm feeding trolls. I'll assume that there are those out there who, in good faith, really don't understand that C++ references are not nullable.

Many other languages made the fatal error of permitting null as valid for all reference types, where every non-builtin is a reference type and they have boxing around classes. Here's some psuedo-Java:

class MyType {
  public void foo() {}
};

void my_fun(MyType instance) {
  instance.foo(); // <-- MAY THROW
}

void another_fun() {
  my_fun(null); // <-- explodes
}

This is semantically similar to the following C++:

class MyType {
public:
  void foo() {}
}

void my_fun(MyType* instance) {
  __check_nonnull(instance); // <-- Check inserted by compiler
  instance->foo();
}

void another_fun() {
  my_fun(nullptr);
}

With implicitly nullable references, every single use of the reference is a candidate for a nullptr.

On the contrary, C++ affords the guarantee that a T& always refers to a valid T.

Of course, all of C++'s guarantees have a caveat: Every guarantee goes out the window if any part of a program contains undefined behavior.

Here's a common "C++ null reference" example that detractors provide:

class MyClass {
public:
  void foo();
};

void do_thing(MyClass& inst) {
  inst.foo();
}

void other_thing() {
  MyClass* inst_ptr = nullptr;
  do_thing(*inst_ptr);
}

Of course, the fact that we dereference inst_ptr means the program behavior is undefined. The call inst.foo() is perfectly legal, and checking that &inst != nullptr is unnecessary.

In fact, the very expression &<anything> != nullptr is completely non-sensical. C++ guarantees that the builtin address-of operator& never returns nullptr. We even get a warning about it from GCC.

Saying "impossible thing might happen" is not useful. Imagine this code:

class MyClass {
public:
  void foo();
};

class UnrelatedClass {
public:
  void foo();
}

void do_thing(MyClass& inst) {
  inst.foo();
}

Saying "inst might be a null reference" is equivalent to saying "inst might actually be an UnrelatedClass" because someone might do this:

void garbage_fn() {
  UnrelatedClass garbage;
  do_thing(reinterpret_cast<MyClass&>(garbage));
}

Both cases are undefined, but for some reason, people still believe that null-references are a thing.

Edit: Wording


Edit to clarify:

I'm not saying that dereferencing null pointers never occurs in practice. What I'm really saying is that there is no use in worrying if a client has dereferenced a null pointer in order to fulfill a reference parameter on your API. There's no meaningful action that you can take.

🌐
Unreal Engine
forums.unrealengine.com › development › programming & scripting › c++
How to return an invalid reference? - C++ - Epic Developer Community Forums
January 13, 2023 - I want to return an invalid reference in this function. Something that I can then check using IsValid() for example. These returns only work for pointers. (NULL, nullptr, 0)… Any way to do it? Thank you so much!!
🌐
Reddit
reddit.com › r/c_programming › return null versus return
r/C_Programming on Reddit: return NULL versus return
November 19, 2023 -

While freeing memory, this is how I proceeded:

// Free `p` and all ancestors of `p`.
void free_family(person *p)
{
    // TODO: Handle base case
    if (p == NULL)
      {
        return NULL;
      }

It appears (ChatGPT) that the following will be the correct way:

// Free `p` and all ancestors of `p`.
void free_family(person *p)
{
    // Handle base case
    if (p == NULL)
    {
        return;
    }

In the context of freeing memory, you typically don't return anything (NULLor otherwise) because you are modifying memory, not producing a result (ChatGPT).

The distinction seems subtle and somewhat vague though makes sense.

Source: https://learning.edx.org/course/course-v1:HarvardX+CS50+X/home

🌐
Quora
quora.com › How-do-you-check-for-NULL-when-passing-by-reference-in-C++
How to check for NULL when passing by reference in C++ - Quora
Answer (1 of 12): So there are three different ways to pass parameters into a function in C++. 1. Pass by Value This is the default for objects like integers, floating point, and classes and structs. The entire object and all its data are binary copied into memory and that copy is passed into th...
Top answer
1 of 9
76

In C++, references can't be null. If you want to optionally return null if nothing is found, you need to return a pointer, not a reference:

Attr *getAttribute(const string& attribute_name) const {
   //search collection
   //if found at i
        return &attributes[i];
   //if not found
        return nullptr;
}

Otherwise, if you insist on returning by reference, then you should throw an exception if the attribute isn't found.

(By the way, I'm a little worried about your method being const and returning a non-const attribute. For philosophical reasons, I'd suggest returning const Attr *. If you also may want to modify this attribute, you can overload with a non-const method returning a non-const attribute as well.)

2 of 9
57

There are several possible answers here. You want to return something that might exist. Here are some options, ranging from my least preferred to most preferred:

  • Return by reference, and signal can-not-find by exception.

    Attr& getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            throw no_such_attribute_error;
    }

It's likely that not finding attributes is a normal part of execution, and hence not very exceptional. The handling for this would be noisy. A null value cannot be returned because it's undefined behaviour to have null references.

  • Return by pointer

    Attr* getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return &attributes[i];
       //if not found
            return nullptr;
    }

It's easy to forget to check whether a result from getAttribute would be a non-NULL pointer, and is an easy source of bugs.

  • Use Boost.Optional

    boost::optional<Attr&> getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            return boost::optional<Attr&>();
    }

A boost::optional signifies exactly what is going on here, and has easy methods for inspecting whether such an attribute was found.


Side note: std::optional was recently voted into C++17, so this will be a "standard" thing in the near future.

Top answer
1 of 4
7

If the function checks the index then a general approach in such a case is to throw an exception std::out_of_range.

Take into account that there is already the member function at in the class template std::vector.

If you may not use exceptions and the task is

P.S. Original task is searching item with property equal to.

then you can use either the standard algorithm std::find_if that returns an iterator or you can write your own function that returns the index that corresponds to the searched element. If there is no such an element then return the size of the vector, For example

#include <iostream>
#include <vector>

template <typename Predicate>
std::vector<int>::size_type find_if( const std::vector<int> &v, Predicate predicate )
{
    std::vector<int>::size_type i = 0;

    while ( i != v.size() && !predicate( v[i] ) ) ++i;

    return i;
}

int main() 
{
    std::vector<int> items = {1, 2, 5, 0, 7};

    auto i = ::find_if( items,  { return item % 2 == 0; } );

    if ( i != items.size() ) std::cout << items[i] << '\n';

    return 0;
}
2 of 4
4

C++ has value semantics. There are nullptrs but there is no null value. A reference always references something. Ergo, there cannot be a reference to null.

Several options you have:

  • throw an exception. Your argument for rejecting them is moot. std::vector::at does exactly that (but I suppose your code is just an example for a more general situation)
  • return a pointer that can be nullptr (not recommended, because then you put the resonsibility on handling it correctly on the caller)
  • return a std::optional. Again this forces the caller to handle the case of "no value returned" but in contrast to returning a nullptr the caller gets a well-designed interface that is hard to use wrong.
  • return an iterator. end is often used to signal "element not found" throughout the standard library, so there will be little surprise if you do the same.
  • perhaps this is not just an example for a different situation, then you should use std::vector::at instead of your handwritten function and be done with it.

P.S. Original task is searching item with property equal to.

You should use std::find to find an item in a container. It returns end of the container when the element cannot be found.