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

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*。如果将对齐分配的返回值强制转换为(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以避免在另一篇文章中引用隐式声明。我认为cast-to-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库中是可用的,那么解决方案就是确保提供了正确的原型。您可以手动插入原型,但不应该这样做。因为它是一个标准库函数,您应该从适当的头获取它的声明,这个头对于这个函数来说是stdlib.h
然而,这个特殊的函数在c11中是新的,显然您使用的是默认为早期标准编译的gcc版本。glibc在一定程度上通过保护c11中的新函数afeature-test macro_ISOC11_SOURCE来支持这一点。这是为了保护您:如果您正在构建为早期标准编写的代码,并且该代码碰巧提供了与c11的一个新函数同名的自己的函数,那么特性测试系统将防止您遭受名称冲突。
如果您确实在为c11编写代码(看起来是这样的),并且如果您的gcc版本有一个支持c11的选项(即-std=c11和/或-std=gnu11),那么启用该选项进行编译是您最好的选择。如果您碰巧有一个glibc版本提供aligned_alloc()而不是一个支持c11模式的编译器版本,那么您可以选择手动确保在包含任何标准头之前将所需的feature test宏定义给编译器。您可以通过源文件顶部的#define或编译器的命令行选项(例如-D_ISOC11_SOURCE=1)来执行此操作。
glibc至少有2.17版的aligned_alloc()(但我认为最早是2.16版)。GCC至少从4.8版开始就有C11模式。如果这些组件的版本至少是最新的,那么在编译命令中添加选项-std=c11(省略gnu扩展)或-std=gnu11(支持gnu扩展)就足够了:

gcc -std=c11 my_program.c

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

10-11 22:46