Here is an SSCCE, showing a simplified version of my code that still does something useful:
//Compile with -O3 -Wsign-conversion
#include <arpa/inet.h>
#include <string>
void _extract_ip_port(struct sockaddr const* addr, std::string* host,unsigned short* port) {
if (addr->sa_family == AF_INET) { //IPv4
struct sockaddr_in const* ipv4 = reinterpret_cast<struct sockaddr_in const*>(addr);
char temp[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipv4->sin_addr, temp, INET_ADDRSTRLEN);
*host = temp;
*port = ntohs(ipv4->sin_port); //<---- ##### WARNING HERE #####
} else { //IPv6
struct sockaddr_in6 const* ipv6 = reinterpret_cast<struct sockaddr_in6 const*>(addr);
char temp[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ipv6->sin6_addr, temp, INET6_ADDRSTRLEN);
*host = temp;
*port = ntohs(ipv6->sin6_port); //<---- ##### WARNING HERE #####
}
}
The problem is that the calls to ntohs(...)
produce something like:
<file>:<line>:<char>: warning: conversion to "unsigned int" from "int" may change the sign
of the result [-Wsign-conversion]
*port = ntohs(ipv6->sin6_port); //<---- ##### WARNING HERE #####
^
As you can see from the documentation linked above, ntohs(...)
has an overload that takes and returns an unsigned short. Since port
, ipv4->sin_port
, and ipv6->sin6_port
are all that, this warning should not happen. So my question: what's going on?
The g++ version is 5.3.0-3ubuntu1~14.04
, and the system is based on ARMv7. I have not been able to reproduce this on x86 or x86-64, so I'm also tagging it arm.