4

我正在研究套接字编程。我的代码按照我想要的方式执行,我可以使用它。但它给了我一个关于编译的警告。

我编译使用

gcc server1.c -o server1 -lpthread

我得到了警告

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

以下代码出现此错误

int newsockfd;
newsockfd = (int)newsockfdd; //this line

我在下面的代码块中使用了newsockfdd(它是int)

if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
    {
        perror("Thread create error");
    }

你可能会说,代码写得不太好(我正在努力让它变得更好)。我知道这个警告是因为与 int 的大小有关。但我真的不知道如何解决它。在我在 pthread_create 语句中输入 (intptr_t) 之前,它在该行显示了一个警告,但那个时候警告是

warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

似乎应该有一个简单的解决方法?但我找不到它。我正在使用 Ubuntu 64 位。这是警告的原因吗?

4

1 回答 1

6

正如评论中所确定的那样,情况是(模重命名以避免混淆newsockfdd作为传递参数或接收参数的出现)

void *serverThread(void *arg) {
    // ...
    int newsockfd = (int)arg;
    // ...
}

和 in main(或从那里调用的函数)

// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
// ..

因此,当int newsockfdd作为参数传递给 时serverThread,它被强制转换为 a void*。最初,该演员表是直接的,但intptr_t插入了中间演员表以删除有关cast to pointer from integer of different size.

并且在中serverThread,收到void*的内容被强制转换为int,导致关于 的警告cast from pointer to integer of different size

该警告也可以通过在intptr_t.

但是,虽然标准允许将整数转换为指针,反之亦然,但结果是实现定义的,并且不能保证int -> void* -> int往返(尽管标准中的脚注说

将指针转换为整数或将整数转换为指针的映射函数旨在与执行环境的寻址结构保持一致。

所以它可能会在这种情况下往返并按预期工作 - 但如果 a 的大小void*小于整数类型的大小[考虑long long -> void* -> long long32 位系统])。

正确的解决方法是避免整数和指针之间的转换,

void *serverThread(void *arg) {
    // ... check that arg isn't NULL
    int newsockfd = *(int *)arg;
    // ...
}

in severThread,将接收到的指针转换为适当类型的指针,并读取指向的值,然后在main

if// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, &newsockfdd) != 0)

传递 的地址newsockfdd

一个警告:如果serverThread从多个地方调用,所有这些地方的调用都需要修复。

于 2012-11-25T14:07:25.553 回答