c - aligned_alloc返回赋值警告

标签 c linux memory memory-management

我正在清理警告并发现以下错误:

warning: assignment makes pointer from integer without a cast buf = aligned_alloc(ALIGN_VALUE,BUF_SZ);

此调用位于函数的最顶部,本质上是:

char* buf;
buf = aligned_alloc(ALIGN_VALUE,BUF_SZ);

据我了解,aligned_alloc 返回一个 void *。如果将aligned_alloc的返回值转换为(char *),我得到:

warning: cast to pointer from integer of different size [-Wint-to-pointer-ast] buf = (char*)aligned_alloc(ALIGN_VALUE,BUF_SZ);

唯一能解决这个问题的是

buf = (char*)(uintptr_t)aligned_alloc(ALIGN_VALUE,BUF_SZ);

我已确保包含 stdlib.h 以避免另一篇文章中提到的隐式声明。我认为强制转换为 char 指针应该可以解决这个问题。据我所知,当 void* 和 uintptr_t 等效时,我不明白为什么转换为 uintptr_t 会解决它。

以下是文件结构的示例

#include <syslog.h>
#include <linux/fs.h>
#include <linux/hdreg.h>
#include <sys/ioctl.h>
#include <sys/mman.h> // mmap
#include <sys/time.h>
#include <unistd.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <pthread.h>

void* ax_read_thread(void* arg)
{
    fprintf(stderr, "read thread started\n");
    ax_priv* priv = (ax_priv*)arg;
    char* buf;
    uint32_t count = 0;

    size_t len, transferred = 0;
    buf = (char*)(uintptr_t)aligned_alloc(ALIGN_VALUE,BUF_SZ);

    if (buf == NULL){
        fprintf(stderr, "Aligned alloc failed\n");
        pthread_exit(NULL);
    }
    while(1){
    //do things
    }
}

感谢您的所有帮助。我现在发现该警告是由于调用编译器时未指示正确的版本而导致的。

最佳答案

这个答案主要总结了评论线程(包括我的和许多其他人的)的观察和建议,并将它们包装在一些说明性散文中。

首先,问题的出现是因为当您使用当前的工具链以当前的形式构建程序时,aligned_alloc()函数没有显式声明。在没有声明的情况下,编译器推断其签名:它猜测该函数返回 int ,并且它的参数类型是通过应用于实际参数类型的默认参数提升获得的。然后,编译器会警告您这些推论(尤其是返回类型)似乎与您实际使用该函数的方式不一致。

假设该函数在您的 C 库中可用,解决方案是确保提供正确的原型(prototype)。您可以手动插入原型(prototype),但您不应该这样做。由于它是标准库函数,因此您应该从相应的 header 中获取其声明,对于该函数来说,该 header 是 stdlib.h .

然而,这个特定的函数是 C11 中的新函数,显然您使用的是默认为早期标准进行编译的 GCC 版本。 Glibc 通过保护 C11 中的新函数(使用 feature-test macro)来部分支持这一点。 , _ISOC11_SOURCE 。这是为了保护您:如果您正在构建为早期标准编写的代码,并且该代码碰巧提供了与 C11 新函数之一同名的函数,功能测试系统可以防止您遭受痛苦名称冲突。

如果您确实是为 C11 编写,情况似乎如此,并且您的 gcc 版本有支持 C11 的选项(即 -std=c11 和/或 -std=gnu11 ),则启用该选项的情况下进行编译是你最好的选择。如果您碰巧有一个提供 aligned_alloc() 的 Glibc 版本但不是支持 C11 模式的编译器版本,那么您可以选择手动确保在包含任何标准 header 之前向编译器定义所需的功能测试宏。您可以通过#define来做到这一点在源文件的顶部,或通过编译器的命令行选项(例如 -D_ISOC11_SOURCE=1 )。

Glibc 确实aligned_alloc()至少从 2.17 版本开始(但我认为最早从 2.16 版本开始)。 GCC 至少从 4.8 版开始就有 C11 模式。如果您的这些组件的版本至少是最新的,那么添加选项 -std=c11 就足够了。 (省略 GNU 扩展)或 -std=gnu11 (以支持 GNU 扩展)到您的编译命令:

gcc -std=c11 my_program.c

关于c - aligned_alloc返回赋值警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42567908/

相关文章:

objective-c - 关于 CATransition 委托(delegate)的内存管理

python-如何显示所有变量的大小

c - HP-UX 上的 PTRACE 编程

c - strcpy 错误返回无响应窗口

c - C中的结构继承

c++ - Linux 和 C/C++ :Appliction created by linking libc-2. 11 并尝试在具有 libc-2.5.so 的 Linux 机器上运行

java - 为什么 Solaris 上的 Sun Java 占用 RSS 内存的两倍以上?

使用套接字复制目录

linux - 如何让这个 init.d 脚本在服务器重启时启动?

linux - 如何从 Python 项目构建 .exe?