【问题标题】:warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]警告:从不同大小的整数转换为指针 [-Wint-to-pointer-cast]
【发布时间】:2012-03-04 07:10:28
【问题描述】:

我的部分代码:

int server_sockfd, client_sockfd; //socket file descriptors of client and server

// ... some code 

if(pthread_create(&vlakno, NULL, handle_client, (int *) client_sockfd) != 0) {
            perror("Error while creating thread.");
        }

我收到 “警告:从不同大小的整数转换为指针 [-Wint-to-pointer-cast]”

我的函数原型:

void *handle_client(void *args);

我发现了这个问题:
link

第一个答案说他应该使用 intptr_t 而不是 int。
我有两个问题:
在我的情况下,int 和 intptr_t 有什么区别?
我该怎么办?

我有两个想法:
第一个:(更改文件描述符的类型)

 int server_sockfd, client_sockfd; //socket file descriptors of client and server

    // ... some code 

    if(pthread_create(&vlakno, NULL, handle_client, (intptr_t *) client_sockfd) != 0) {
                perror("Error while creating thread.");
            }

或第二个想法:(仅在转换函数 pthread_create 中更改类型)

intptr_t server_sockfd, client_sockfd; //socket file descriptors of client and server

        // ... some code 

        if(pthread_create(&vlakno, NULL, handle_client, (int *) client_sockfd) != 0) {
                    perror("Error while creating thread.");
                }

编辑:
在函数 handle_client 我想这样做:

int clientSocket;
clientSocket = (int)args;

我真的很抱歉用户 cnicar 或类似的东西.. 他不幸删除了他的答案,但没关系。
他的解决方案是使用 (void *),它首先抛出了同样的错误,但它可能是由于 eclipse 的不良行为造成的 :( 所以给他留言:
好的,谢谢它现在看起来很好...... Eclipse 仍然抛出这个警告,但是当我打开和关闭它两次后,用你的编辑很好地编辑它:) 非常感谢

【问题讨论】:

  • 如何传递一个指向 FD 的指针,如&client_sockfd
  • @KerrekSB 如果您的建议可以接受,请查看我的编辑。 (不确定我何时使用指针)

标签: c sockets pointers client-server


【解决方案1】:
(int *) client_sockfd

client_sockfd 不是指针。这是一个int,与int * 的大小不同。它会告诉你这一点。

pthread_create() 的最后一个参数是void *,它是指向您要传递到该特定线程的数据的指针。看来您正在尝试将 client_sockfd 的整数值转换为指针并传递它。这通常不是你会做的事情,但如果你真的想要避免警告,那么你需要使用与指针大小相同的东西,这就是intptr_t 给你的。在您的系统上,int 很可能是 4 个字节,intptr_t(和 void *)是 8 个字节,但这取决于平台。虽然您可以安全地从 32->64->32 位开始,但编译器会警告您您有不同的大小。

【讨论】:

  • pthread_create 的最后一个参数也可以传递整数参数,只要该值通过实现从 intvoid *int 的转换安全地适合 void *。跨度>
  • 仅仅因为你可以做某事并不意味着你应该这样做。话虽这么说……这正是我回答的最后一段所说的。我将添加一些明确性来明确讨论尺寸。
【解决方案2】:

您已将client_sockfd 声明为int。您不应该以这种方式将其转换为 int *

使用& 运算符来获取client_sockfd 的地址,而不是如果您打算给client_sockfd 提供一个指针

pthread_create(&vlakno, NULL, handle_client, &client_sockfd)
                                          // ^ & operator

请注意client_sockfd 的生命周期,它必须比线程寿命更长以防止出现竞争条件(请参阅 cmets)。


intintptr_t 的区别在于int 用于保存整数,而intptr_t 用于保存整数形式的地址。 intptr_t 保证能够持有指针,而int 则不能。

如果您的意图是传递client_sockfd,请将其转换为intptr_t

pthread_create(&vlakno, NULL, handle_client, (intptr_t)client_sockfd)

【讨论】:

  • 传递&client_sockfd 不安全 除非您添加同步以确保调用者在新线程使用指向的值之前不会返回!尽管有警告,OP 的原始代码是正确的,通过uintptr_t 进行无用的转换可以避免警告。
  • 要明确:OP 的版本只有在 int-to-void *-to-int 往返不安全的晦涩编译器上存在错误。据我所知,不存在这样的编译器——当然也不存在也支持 POSIX 线程的编译器。另一方面,您的版本在每个系统上都存在严重的竞争条件错误。
  • @R.. 同时,如果整数值是 int 而不是 @987654344,C 不保证在 往返 之后保留整数值@ 或 intptr_t
【解决方案3】:

(int *) client_sockfd 不等同于&client_sockfd

第一种形式将client_sockfd 的值转换为int *,第二种形式产生一个指向client_sockfd 的指针。

这是您必须为 pthread_create 最后一个参数使用的后一个表达式。

【讨论】:

  • 传递&client_sockfd 是不正确且极其不安全的,除非您添加同步以确保其生命周期不会在新线程使用它之前结束。尽管有警告,OP 的代码是正确的。您可以通过uintptr_t 使用无用的演员来消除警告。
  • @R.. 根据handle_client 的实现方式,将client_sockfd 的副本转换为指针类型可能是错误的。关于对象client_sockfd 的生命周期,OP 问题中没有任何内容告诉我们它没有静态存储持续时间,或者描述符可以以不安全的方式访问。
  • 我假设它不是静态的,因为线程的静态存储持续时间只是编写废话代码的公式。实际上,即使没有“线程”一词,情况也是如此。我同意 handle_client 函数可能需要一个指针,但我对此表示怀疑,因为 OP 提出了关于警告的问题,而不是关于为什么 handle_client 崩溃的问题......
猜你喜欢
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 2014-03-20
  • 1970-01-01
  • 2022-12-11
相关资源
最近更新 更多