Compiler Warning C4801

 

The latest version of this topic can be found at Visual Studio 2017 Documentation. Return by reference is not verifiable: reason

You cannot store a tracking reference into a local variable and then return it verifiably.

A reference can only be verifiably returned when it can be tracked by the verifier from creation to return point and when it is a reference to an element of an array, or a member of a class.

For more information, see Peverify.exe (PEVerify Tool).

A reference must remain on the stack from creation to return in order to be verifiable.

C4801 is always issued as an error. You can turn off this warning with the #pragma warning or /wd; see warning or /w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4, /Wall, /wd, /we, /wo, /Wv, /WX (Warning Level) for more information.

Example

C4801 will be generated if the verifier cannot see the address taken, so it must assume that it might be an unverifiable reference. The following sample generates C4801.

// C4801.cpp  
// compile with: /clr:safe /c  
int% f(int% p) {  
   return p;   // C4801  
}  

Example

The following sample generates C4801.

// C4801_b.cpp  
// compile with: /clr:safe /c  
  
int% f(int i, array<int>^ ar) {  
   int x;  
   int% bri = x;   // cannot return a byref to a local.  
   if (i < ar->Length) {  
      bri = ar[i];   // this byref is ok.  
   }  
  
   return bri;   // C4801 not returned within the basic block  
}  

Example

C4801 can also occur if you attempt to dereference and return a reference value in a try block. This will result in code that cannot be verified because the stack is cleared at the end of a try block, destroying any return value on the stack. Instead, dereference the reference type and assign it to a variable, to ensure that no exception is thrown. Then, at the end of the function, dereference the reference type again and return it.

The following sample generates C4801.

// C4801_c.cpp  
// compile with: /clr:safe  
using namespace System;  
  
ref class StackEmptyException : public System::Exception {};  
ref class StackFullException : public System::Exception {};  
  
template <typename T>  
ref struct Stack {  
  
   Stack() {  
      topElem = -1;   // initialize stack  
      stackPtr = gcnew array<T>(10);  
   }  
  
   void push(const T%);  
   T% top();  
  
private:  
   int topElem;    
   array<T>^ stackPtr;    
};  
  
template <typename T>   
T% Stack<T>::top() {  
   try {  
      return stackPtr[topElem];   // C4801  
      // Try the following line instead.  
      // T% deadstore = stackPtr[topElem] ;  
   }  
  
   catch (System::IndexOutOfRangeException ^ e) {  
      throw gcnew StackEmptyException();  
   }  
  
   catch (System::Exception ^ e) {  
      throw;  
   }  
  
   return stackPtr[topElem] ;  
}  
  
int main() {  
   typedef Stack<Int32> IntStack;  
   IntStack ^ is = gcnew IntStack();  
  
   int i = 1;  
   while (1) {  
      try {  
         is->push(i++);  
      }  
      catch (System::Exception ^ e) {  
         break;  
      }  
      Console::Write("{0} ", is->top());  
   }  
}