2014-06-13 70 views
1

我有一个客户端和服务器之间的接口,客户端发送(1)一个无符号的值,(2)一个标志,指示值是否有符号/无符号。然后,服务器会将无符号值转换为适当的类型。安全地转换unsigned和signed int

我后来发现这是实现定义的行为,我一直在阅读它,但我似乎无法找到一个完全安全的合适解决方案?我读过关于类型双击,指针转换和memcpy。

只会使用联合类型的工作?包含signed和unsigned int的UnionType以及signed/unsigned标志。对于有符号值,客户端设置联合的签名部分,服务器读取签名部分。相同的未签名部分。还是我完全误解了一些东西?

问题:我怎么知道这种情况下针对特定场景的特定行为,例如,在PPC上的windriver diab?我在如何找到这样的文档方面有点遗憾。

+0

除非您遇到使用类似补码或符号大小的系统,否则我认为您使用的所有内容都将以同样的方式定义unsigned-> signed转换。 – user2357112

+0

当客户端发送一个无符号值但发送了签名标志时应该发生什么? –

+0

你的代码如何处理签名标志? (因为C++有一个静态类型系统,你需要在编译时指定你的类型) –

回答

0

联合解决方案将要求您让客户端和服务器都使用相同的表示形式,这不是一个好主意。 (例如,big-endian和little-endian系统都很常见)。

你应该以某种方式序列化值。但是,您只需为每种类型单独执行此操作。

例如(伪码)

void send_signed(int32_t x) 
{ 
    send(1, "s"); 
    send(sizeof x, serialized x); 
} 

void send_unsigned(uint32_t x) 
{ 
    send(1, "u"); 
    send(sizeof x, serialized x); 
} 

和接收机;你首先阅读这个类型。如果它是“s”,那么你反序列化一个带符号的int并且与它有关的东西;如果它是“你”,那么你反序列化一个unsigned int(到一个不同的变量),并用它做一些事情。

+0

用户需要做什么关于客户端和服务器的字节顺序? –

+0

如果我们假设排序不是问题,那么联盟解决方案会起作用吗? – polemic

+0

@Matt McNabb,'serialized x'需要什么?只要发送's'或'u',唯一的要求就是将int x转换为'(unsigned int)x',比如说'unsigned int xmit = int whatever'并发送。然后在接收端,如果's'被设置,则'int rcvd =(int)xmit'负责签名。例如:int xmit = -5678被发送为:'11111111111111111110100111010010',当's'被接收时,'int rcvd =(int)xmit'的强制转换在另一端恢复正确的符号:-5678。还有什么我失踪? ('x> 2,147,483,647'这样的情况是行不通的,但是? –

1

转换unsignedint只是在形式上存在问题。在实践中,所有现存的平台使用二进制补码表示,其中unsignedintintunsigned(其在形式上明确定义)完全相反。所以’没问题。


看一看Wikipedia’s article on the UNIVAC对于其中使用一个’的补表示一个平台的一个例子,例如对于12位和36位位字。

相关问题