G
Generic Usenet Account
Compile the following snippet of code and run it. If the program spits
out bat:bat instead of bat:zat, what would you say? Would you say that
the compiler has a problem, or would you lay the blame on "undefined
execution of function parameters" in the C/C++ standard and "sequence
points"?
/////// Code snippet begins ///////
#include <iostream>
char foo[10]="cat";
char* writestring()
{
foo[0]='b';
return foo;
}
char* write2()
{
foo[0]='z';
return foo;
}
int main(void)
{ std::cout << writestring() << ":" << write2() << std::endl; }
/////// Code snippet ends ///////
Thanks,
Bhat
[Purists who hold that this NG is meant to discuss compiler neutral,
standard C++ issues only may not proceed beyond this point;-)]
For those of you who are "trivially inclined", here's some
background......
I stumbled upon a "bug" in my C++ compiler (g++ 3.3.1), which I
promptly reported to Bugzilla. The code snippet above was actually
provided by someone from the GCC volunteer community. They attributed
the unexpected behavior to the undefined behavior of execution of
function parameters and sequence points. In my original code snippet,
I was maintaining an STL map between IP addresses e.g. 105.52.20.33,
5000 and 47.32.68.95, 6000.
When I displayed the entries in the map, the second IP address was
displayed incorrectly. So instead of the mapping:
105.52.20.33, 5000 >>-->> 47.32.68.95, 6000
I got
105.52.20.33, 5000 >>-->> 105.52.20.33, 6000
The bug does not manifest when the code is compiled using native
Solaris C++
compiler version "WorkShop Compilers 5.0 02/04/10 C++ 5.0 Patch
107311-17"
Here's my original code snippet
/////// Code snippet begins ///////
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <map>
#include <iostream>
using namespace std;
struct addrLessThan
ublic binary_function<const struct sockaddr_in,
const
struct sockaddr_in, bool>
{
bool operator()(const struct sockaddr_in addr1, const struct
sockaddr_in
addr2) const
{
bool retVal = true;
string addrStr1 = inet_ntoa(addr1.sin_addr);
string addrStr2 = inet_ntoa(addr2.sin_addr);
if(addrStr1 > addrStr2)
retVal = false;
else if(addrStr1 == addrStr2)
retVal = (addr1.sin_port < addr2.sin_port);
return retVal;
}
};
typedef map<struct sockaddr_in, struct sockaddr_in, addrLessThan>
IpV4AddrMap;
main()
{
struct sockaddr_in actualAddress, mappedAddress;
actualAddress.sin_port=5000;
actualAddress.sin_addr.s_addr = inet_addr("105.52.20.33");
mappedAddress.sin_port=6000;
mappedAddress.sin_addr.s_addr = inet_addr("47.32.68.95");
IpV4AddrMap map;
map[actualAddress] = mappedAddress;
IpV4AddrMap::iterator itor = map.find(actualAddress);
if(itor != map.end())
{
cout << "Key: " << inet_ntoa(itor->first.sin_addr)
<< ", " << itor->first.sin_port << endl
<< "Value: " << inet_ntoa(itor->second.sin_addr)
<< ", " << itor->second.sin_port << endl
<< endl;
}
return 0;
}
/////// Code snippet ends ///////
For more details, you can go to
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22265
out bat:bat instead of bat:zat, what would you say? Would you say that
the compiler has a problem, or would you lay the blame on "undefined
execution of function parameters" in the C/C++ standard and "sequence
points"?
/////// Code snippet begins ///////
#include <iostream>
char foo[10]="cat";
char* writestring()
{
foo[0]='b';
return foo;
}
char* write2()
{
foo[0]='z';
return foo;
}
int main(void)
{ std::cout << writestring() << ":" << write2() << std::endl; }
/////// Code snippet ends ///////
Thanks,
Bhat
[Purists who hold that this NG is meant to discuss compiler neutral,
standard C++ issues only may not proceed beyond this point;-)]
For those of you who are "trivially inclined", here's some
background......
I stumbled upon a "bug" in my C++ compiler (g++ 3.3.1), which I
promptly reported to Bugzilla. The code snippet above was actually
provided by someone from the GCC volunteer community. They attributed
the unexpected behavior to the undefined behavior of execution of
function parameters and sequence points. In my original code snippet,
I was maintaining an STL map between IP addresses e.g. 105.52.20.33,
5000 and 47.32.68.95, 6000.
When I displayed the entries in the map, the second IP address was
displayed incorrectly. So instead of the mapping:
105.52.20.33, 5000 >>-->> 47.32.68.95, 6000
I got
105.52.20.33, 5000 >>-->> 105.52.20.33, 6000
The bug does not manifest when the code is compiled using native
Solaris C++
compiler version "WorkShop Compilers 5.0 02/04/10 C++ 5.0 Patch
107311-17"
Here's my original code snippet
/////// Code snippet begins ///////
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <map>
#include <iostream>
using namespace std;
struct addrLessThan
const
struct sockaddr_in, bool>
{
bool operator()(const struct sockaddr_in addr1, const struct
sockaddr_in
addr2) const
{
bool retVal = true;
string addrStr1 = inet_ntoa(addr1.sin_addr);
string addrStr2 = inet_ntoa(addr2.sin_addr);
if(addrStr1 > addrStr2)
retVal = false;
else if(addrStr1 == addrStr2)
retVal = (addr1.sin_port < addr2.sin_port);
return retVal;
}
};
typedef map<struct sockaddr_in, struct sockaddr_in, addrLessThan>
IpV4AddrMap;
main()
{
struct sockaddr_in actualAddress, mappedAddress;
actualAddress.sin_port=5000;
actualAddress.sin_addr.s_addr = inet_addr("105.52.20.33");
mappedAddress.sin_port=6000;
mappedAddress.sin_addr.s_addr = inet_addr("47.32.68.95");
IpV4AddrMap map;
map[actualAddress] = mappedAddress;
IpV4AddrMap::iterator itor = map.find(actualAddress);
if(itor != map.end())
{
cout << "Key: " << inet_ntoa(itor->first.sin_addr)
<< ", " << itor->first.sin_port << endl
<< "Value: " << inet_ntoa(itor->second.sin_addr)
<< ", " << itor->second.sin_port << endl
<< endl;
}
return 0;
}
/////// Code snippet ends ///////
For more details, you can go to
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22265