Not initialized out argument error

bearophile via Digitalmars-d digitalmars-d at puremagic.com
Tue Jun 17 03:30:05 PDT 2014


Walter Bright:

>> How much often do I need to write a function like foo?
>> I think it's uncommon.
>
> I suspect that is a guess.

I have just studied all usages of out arguments in my code, and I 
have never left an out argument uninitialized inside the function 
body. When I use an out argument, I always put something inside 
it in the function body.

---------------

I have also taken a look at Phobos. I have not done an equivalent 
study on the Phobos code, but I have seen that out arguments are 
uncommon in Phobos. The following are almost all the usages:


void getTimes(in char[] name,
               out SysTime accessTime,
               out SysTime modificationTime)
{
     version(Windows)
     {
         with (getFileAttributesWin(name))
         {
             accessTime = 
std.datetime.FILETIMEToSysTime(&ftLastAccessTime);
             modificationTime = 
std.datetime.FILETIMEToSysTime(&ftLastWriteTime);
         }
     }
     else version(Posix)
     {
         stat_t statbuf = void;

         cenforce(stat(toStringz(name), &statbuf) == 0, name);

         accessTime = SysTime(unixTimeToStdTime(statbuf.st_atime));
         modificationTime = 
SysTime(unixTimeToStdTime(statbuf.st_mtime));
     }
}


real remquo(real x, real y, out int n) @trusted nothrow @nogc  
/// ditto
{
     version (Posix)
         return core.stdc.math.remquol(x, y, &n);
     else
         assert (0, "remquo not implemented");
}




real frexp(real value, out int exp) @trusted pure nothrow @nogc
{
     ushort* vu = cast(ushort*)&value;
     long* vl = cast(long*)&value;
     int ex;
     alias F = floatTraits!(real);

     ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
     static if (real.mant_dig == 64)     // real80
     {
         if (ex)
         {   // If exponent is non-zero
             if (ex == F.EXPMASK) // infinity or NaN




     static void prepareStream(ref File file, DWORD stdHandle, 
string which,
                               out int fileDescriptor, out HANDLE 
handle)
     {
         fileDescriptor = file.isOpen ? file.fileno() : -1;
         if (fileDescriptor < 0)   handle = 
GetStdHandle(stdHandle);
         else                      handle = file.windowsHandle;

         DWORD dwFlags;
         if (GetHandleInformation(handle, &dwFlags))
         {
             if (!(dwFlags & HANDLE_FLAG_INHERIT))
             {
                 if (!SetHandleInformation(handle,
                                           HANDLE_FLAG_INHERIT,
                                           HANDLE_FLAG_INHERIT))




     /// Common case of getting integer and boolean options.
     int getOption(SocketOptionLevel level, SocketOption option, 
out int32_t result)
     {
         return getOption(level, option, (&result)[0 .. 1]);
     }



   void read(out byte x);
   void read(out ubyte x);       /// ditto
   void read(out short x);       /// ditto
   void read(out ushort x);      /// ditto
   void read(out int x);         /// ditto
   void read(out uint x);        /// ditto
   void read(out long x);        /// ditto
   void read(out ulong x);       /// ditto
   void read(out float x);       /// ditto
   void read(out double x);      /// ditto
   void read(out real x);        /// ditto
   void read(out ifloat x);      /// ditto
   void read(out idouble x);     /// ditto
   void read(out ireal x);       /// ditto
   void read(out cfloat x);      /// ditto
   void read(out cdouble x);     /// ditto
   void read(out creal x);       /// ditto
   void read(out char x);        /// ditto
   void read(out wchar x);       /// ditto
   void read(out dchar x);       /// ditto



dchar decodeFront(S)(ref S str, out size_t numCodeUnits)
     if (!isSomeString!S && isInputRange!S && 
isSomeChar!(ElementType!S))
in
{
     assert(!str.empty);
}
out (result)
{
     assert(isValidDchar(result));
}
body
{
     immutable fst = str.front;

     if (fst < codeUnitLimit!S)
     {




     void checkName(ref string s, out string name) // rule 5
     {
         mixin Check!("Name");

         if (s.length == 0) fail();
         int n;
         foreach(int i,dchar c;s)
         {
             if (c == '_' || c == ':' || isLetter(c)) continue;
             if (i == 0) fail();
             if (c == '-' || c == '.' || isDigit(c)
                 || isCombiningChar(c) || isExtender(c)) continue;
             n = i;
             break;
         }
         name = s[0..n];
         s = s[n..$];
     }




private void regProcessNthValue(HKEY hkey, scope void 
delegate(scope LONG delegate(DWORD, out string)) dg)
{
     DWORD cValues;
     DWORD cchValueMaxLen;

     immutable res = regGetNumValues(hkey, cValues, 
cchValueMaxLen);
     assert(res == ERROR_SUCCESS);

     wchar[] sName = new wchar[cchValueMaxLen + 1];

     dg((DWORD index, out string name)
     {
         DWORD cchName;
         immutable res = regEnumValueName(hkey, index, sName, 
cchName);
         if (res == ERROR_SUCCESS)
         {
             name = toUTF8(sName[0 .. cchName]);
         }
         return res;
     });
}


How many of such Phobos cases leave on purpose not explicitly 
initialized an out argument inside the function body?

Bye,
bearophile


More information about the Digitalmars-d mailing list