spark/core-firmware — pull request #234 by technobly (2014-07-01 20:13:30+00:00)
Title: Ipaddress warning fix

Fixed the issues surrounding these warnings in the compiler:
```
../inc/spark_wiring_ipaddress.h: In member function 'IPAddress::operator uint32_t()':
../inc/spark_wiring_ipaddress.h:53:52: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
operator uint32_t() { return *((uint32_t*)_address); };
^
../inc/spark_wiring_ipaddress.h: In member function 'bool IPAddress::operator==(const IPAddress&)':
../inc/spark_wiring_ipaddress.h:54:72: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
^
../inc/spark_wiring_ipaddress.h:54:105: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
```

* [Info on Strict Aliasing Rule](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) Can be very bad, typically best to avoid.
* Implementation of Equals operators were moved from header file to source file.
* Implementation of Equals operators were changed to prevent [type-punning].(http://en.wikipedia.org/wiki/Type_punning)
* Changed implementation of Copy operator, Equals operator and Constructor for uint32_t types due to endianness of octet vs. array with memcpy and memcmp do not work as desired.
* Moved comment for raw_address() method to the correct location.
* Slight style tweak for pointers.

### Test code follows ###

I know it's not quite unit test worthy, but it helped me! I iterated through each failure as well, checking for Tests 1 - 6 to fail. Tests 7 and 8 are manually checked.

```cpp
/*
* IPAddress Class Test Application
* BDub @ Technobly (c) 2014
*
*/

#include "application.h"
#include "spark_disable_wlan.h" // (for faster local debugging only)

IPAddress myIP(10,0,0,2); // Constructor 4 byte argument
IPAddress myIP2( 167772162UL ); // Constructor uint32_t, 10.0.0.2 as 10*256^3+0*256^2+0*256+2
IPAddress myIP3(10,0,0,2); // Constructor 4 byte argument
IPAddress myIP4; // Constructor default
uint8_t myArray[] = {10,0,0,2};
uint8_t * myPtr;
uint8_t test = 0;

void setup()
{
pinMode(D7,OUTPUT);
myPtr = myArray;
myIP4 = 167772162UL; // Copy uint32_t operator

Serial.begin(9600); // Wait to open serial terminal, press enter.
while(!Serial.available()); // Local debugging, no need to ping BG tasks.

// Run tests
if(myIP == 167772162UL && ++test > 0) // 1) Equals operator uint32_t
if(myIP == myIP2 && ++test > 0) // 2) Constructor uint32_t == IPAddress object
if(myIP == myIP3 && ++test > 0) // 3) Equals operator IPAddress object
if(myIP == myIP4 && ++test > 0) // 4) Copy operator uint32_t == IPAddress object
if(myIP == myArray && ++test > 0) // 5) IPAddress object == uint8_t*
if(myIP == myPtr && ++test > 0) { // 6) IPAddress object == uint8_t*
// 7) Printable IPAddress
Serial.print("These should equal -> 10.0.0.2 == "); Serial.println(myIP);
test++;
// 8) No warnings?
Serial.println("There should also be no warnings from the IPAddress Class from the compiler!");
test++;
}

if(test < 8) {
// Print test that failed
Serial.print("Test # "); Serial.print(test+1); Serial.println(" Failed!");
digitalWrite(D7,HIGH); // Turn on D7 solid if any failure...
}
else {
Serial.print("All "); Serial.print(test); Serial.println(" Tests Passed!");
while(1) { // All tests passed, blink D7
digitalWrite(D7,HIGH);
delay(100);
digitalWrite(D7,LOW);
delay(100);
}
}
}

void loop()
{
// do nothing
}
```