我这里有一些看起来很可怕的代码,对我自己来说,我将永远不必再看到它或对其进行调试(它将被完全不同的编程语言隐藏),以这种方式进行转换是否会产生开销?
int main (int argc, char *argv[]){
int s;
struct sockaddr_in saddr, caddr;
socklen_t addrlen = sizeof(struct sockaddr_in);
inet_aton(argv[1], &saddr.sin_addr);
uint16_t port = htons(atoi(argv[2]));
int result;
int bklog = 10;
int i,n;
int *sockVett;
sockVett = new int[nESP];
while(1) {
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == -1 ){
cout << "socket() failed\n";
return -1;
}
for(i=0; i < nESP; i++){
sockVett[i] = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
}
saddr.sin_family = AF_INET;
saddr.sin_port = port;
saddr.sin_addr.s_addr = INADDR_ANY;
bind(s, (struct sockaddr *) &saddr, sizeof(saddr));
listen (s, bklog);
for(i=0; i < nESP; i++){
if(debug) printf("SockVett[%d] is waiting for connection..\n", i+1);
sockVett[i] = accept(s, (struct sockaddr *) &caddr, &addrlen);
if(debug) printf("SockVett[%d] connected\n", i+1);
}
if(debug) printf("All ESP connected\n\n ---Start program---\n");
}
}
(是的,我了解令人难以置信的违反代码的行为,但是有必要向上转发类型责任)
*在旁注中,这可以做得更清洁吗? (我什至会接受汇编程序建议)
答案 0 :(得分:1)
在大多数现代C实现中,将一种类型的指针转换为另一种类型的指针的性能成本为零或可忽略不计。更大的担忧将是在通用寄存器和浮点寄存器之间移动数据。
您注意到,问题中的代码违反了C的严格别名规则,尽管您的C实现可能支持它。但是,有两种选择:
如果in
,out
的情况以及您的C实现支持以float
的身份访问内容,请使用:
float *fin = in, *fout = out;
fout[0] = fin[1] - fin[0];
如果不支持以float
的身份访问数据,请使用:
char *p = in;
float c, d, e;
memcpy(&d, p, sizeof d);
memcpy(&c, p + sizeof d, sizeof c);
e = c - d;
memcpy(out, &e, sizeof e);
请注意,尽管memcpy
在C抽象机中名义上更糟(它逐个复制字节),但是良好的C实现将优化此代码。 (如果in
和out
的对齐方式没有问题,那么对于典型的处理器,好的编译器应生成两个加载,减法和存储。如果考虑对齐方式,则应采用某种形式的可能需要未对齐的装载和存储。但是在任何情况下都需要。)