在C语言中,投射指针是否有开销?

时间:2018-12-06 19:50:47

标签: c performance pointers dynamic casting

我这里有一些看起来很可怕的代码,对我自己来说,我将永远不必再看到它或对其进行调试(它将被完全不同的编程语言隐藏),以这种方式进行转换是否会产生开销?

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");


    }
}

(是的,我了解令人难以置信的违反代码的行为,但是有必要向上转发类型责任)

*在旁注中,这可以做得更清洁吗? (我什至会接受汇编程序建议)

1 个答案:

答案 0 :(得分:1)

在大多数现代C实现中,将一种类型的指针转​​换为另一种类型的指针的性能成本为零或可忽略不计。更大的担忧将是在通用寄存器和浮点寄存器之间移动数据。

您注意到,问题中的代码违反了C的严格别名规则,尽管您的C实现可能支持它。但是,有两种选择:

如果inout的情况以及您的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实现将优化此代码。 (如果inout的对齐方式没有问题,那么对于典型的处理器,好的编译器应生成两个加载,减法和存储。如果考虑对齐方式,则应采用某种形式的可能需要未对齐的装载和存储。但是在任何情况下都需要。)