Is it really assumed that the link is passed as a pointer

I have a function defined as follows:

void doSomethingWithCustomer (const Customer &customer); 

One of my development engineers called it the following:

 Customer *customer = order.getCustomer(); doSomethingWithCustomer (*customer); 

Unfortunately, the getCustomer method can return nullptr if the order is not tied to the client. If getCustomer returns nullptr, then the application does not crash during a call to doSomethingWithCustomer , but rather inside a function that uses a client link.

Of course, the correct way to write this is to verify that the client is not nullptr first, and then call the function if we have a valid client. Usually we expect that if the function / method has a reference argument, then the caller checks its validity (which was not here), and not the argument verification function itself.

I know that Visual Studio 2010 (and earlier versions) passes links, actually passing a pointer, but I wonder if this is indicated somewhere in the C ++ standard. Is it possible to consider that a link is always passed as a pointer (personally, I would not rely on this, but it is interesting to know)?

Is it possible to tell Visual Studio that when transferring a link, it should automatically dereference it first and crash during a call, and then somewhere much deeper (this can be enough in the debug version)?

+6
source share
6 answers

Is it possible to assume that the link is passed as a pointer?

No, it is not. The standard does not stipulate that the link should be implemented from the point of view of the pointer.

How to actually implement a link is an implementation detail that the standard does not take into account for implementation. It describes only the expected behavior from the link, and one of them is that the link can never be NULL in the standard matching program.

If your function parameter must be NULL sometimes, then you must pass it as a pointer.

+4
source

Not. It is fully implemented.

For diagnostic purposes, I created a small type of container that checks the parameter. Then you declare the function / method:

 void doSomethingWithCustomer(const t_nonnull<const Customer>& pCustomer); 

where type t_nonnull confirmed the parameter when building. However, I found it more useful to just use links more often (IOW, do not return a pointer in this case - just think about the error to gain access to the client when the client does not exist).

+1
source

The behavior is undefined. This means that you cannot rely on any particular error detection method. A good compiler can warn you at compile time, and the other can completely mask the error depending on how you use the variable. You are responsible for ensuring that the links are never NULL.

+1
source

This is not observed, and it does not matter. A program using this code has undefined behavior because it shares a null pointer.

+1
source

A link can be implemented using an internal pointer (for example, what happens in Java). But below, two differences are important between them:

  • By default, a pointer can be bound to another object. However, the link has a permanent binding to the object that was initialized.
  • The pointer can be set to 0, but the link cannot

Similarly, T& equivalent to T* const .

You do not need to inform the compiler about the delay of the variable, because this happens on its own.

 void foo(T&); T t, *p = 0; foo(t); // the only way to pass reference foo(*p); // the only way to pass reference 
0
source

As others have said, the standard does not impose how links should be applied. To catch "dereferenced NULLs passed as reference" errors earlier, you can do this inside your functions:

 void doSomethingWithCustomer (const Customer &customer) { assert(&customer); //... rest of function } 
0
source

All Articles