Rotor FUBAR of the day: Why did IPAddress take a public long constructor?

I've included the code below.  Notice that the IPAddress can be constructed using a long for the address.  Also note there is an *internal* version that only uses an int.  An IPv4 address only contains 32 bits, so it makes sense to use the int.  Hell, they even make sure more than 32 bits aren't specified in the long address that they consume.

So why did this happen?  You might say, “Hey, IPv6“, but then you wouldn't be knowing much about IPv6 since it is 128 bits.  I haven't seen any Int128's laying around, else it would be nice if a long mapped to a 128 bit integer in a 64 bit platform (maybe it does and maybe that is the reason.  I don't play with 64 bit so I just don't know).

I've wondered this question for quite some time.  Thankfully the methods are being deprecated in favor of byte array versions that can take either 32 bits or 128 bits depending on the address you are trying to specify.  This allows you to use either IPv4 or IPv6 which is kinda nice.  Well, I'll chalk this up to my rotor FUBAR of the day, unless one of the System.Net guys wants to jump in and provide an explanation.  The code comments sure don't explain things.  They just mention the 32 bit version is for Winsock compliance.  Again, I don't know where this long is coming from, and I've never worked with a long anything when working with sockets before.  Enlighten me someone, please!

        /// <include file='doc\IPAddress.uex' path='docs/doc[@for="IPAddress.IPAddress"]/*' />
        /// <devdoc>
        ///    <para>
        ///       Initializes a new instance of the <see cref='System.Net.IPAddress'/>
        ///       class with the specified
        ///       address.
        ///    </para>
        /// </devdoc>
        public IPAddress(long newAddress) {
            if (newAddress<0 || newAddress>0x00000000FFFFFFFF) {
                throw new ArgumentOutOfRangeException("newAddress");
            }
            m_Address = newAddress;
        }

        //
        // we need this internally since we need to interface with winsock
        // and winsock only understands Int32
        //
        internal IPAddress(int newAddress) {
            m_Address = (long)newAddress & 0x00000000FFFFFFFF;
        }

Published Monday, February 23, 2004 10:34 PM by Justin Rogers
Filed under:

Comments

Tuesday, February 24, 2004 2:34 AM by Thomas Tomiczek

# re: Rotor FUBAR of the day: Why did IPAddress take a public long constructor?

One World:

CLS.

CLS does not allow usigned variables. So UInt (which IPV4 ACTUALLY is does not work). So - in rder to handle all "official" representations of IP in single int form, they had to make the variable an Int64.

You get the same thing with port numbers on sockets, interesting enough, although there they do not get into compatibility mode. he IpEndPoint has an int as port number - interesting in that port numbers run up 65536 and int is 32 bits. But heck, then: CLS does not allow an ushort to be used :-)
Friday, February 27, 2004 8:38 PM by Justin Rogers

# re: Rotor FUBAR of the day: Why did IPAddress take a public long constructor?

Darn, sorry for the long delay in reply, the flu seems to have found me.

This is a perfect response, since it really points out why certain designs were adopted. I'm glad someone had the insight to point this out, since I probably would have overlooked this.

Why? Well, because having used sockets for so long, the sign of a 32-bit integer has never really mattered. Behind the scenes a negative integer is simply mapped to an appropriate IP, and you never find yourself typing the integer format of an IP address anyway.

I think this FUBAR has been reversed and I'll graciously accept that the *right thing* was done.

Leave a Comment

(required) 
(required) 
(optional)
(required)