You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

faccessat及AT_*宏未定义:Ubuntu WSL编译失败修复咨询

编译faccessat相关代码时的未定义标识符问题

问题背景

这段C代码在MacOS 12环境能正常运行,但在WSL的Ubuntu环境下用clang 14编译时出错。编译命令为:
clang -lrt -pthread -I/usr/include -std=c11 -o copy copy.c

用户已尝试重装build-essentials、clang、gcc、glibc,查看fcntl.h未找到AT_*系列定义,但手册说明该头文件应包含这些常量,需要解决编译报错问题。

待编译代码

// SYSTEM INCLUDE FILES
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/uio.h>

// C STANDARD LIBRARY INCLUDE FILES
#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    char *source = "file1.txt";
    char *dest = "file2.txt";

    printf("%d\n", faccessat(AT_FDCWD, source, F_OK | R_OK | W_OK, AT_SYMLINK_NOFOLLOW));
    printf("%d\n", faccessat(AT_FDCWD, dest, F_OK | R_OK | W_OK, AT_SYMLINK_NOFOLLOW));
    printf("Value of errno: %s\n", strerror(errno));

    return 0;
}

编译错误信息

copy.c:21:20: warning: implicit declaration of function 'faccessat' is invalid in C99 [-Wimplicit-function-declaration]
    printf("%d\n", faccessat(AT_FDCWD, source, F_OK | R_OK | W_OK, AT_SYMLINK_NOFOLLOW));
                   ^
copy.c:21:30: error: use of undeclared identifier 'AT_FDCWD'
    printf("%d\n", faccessat(AT_FDCWD, source, F_OK | R_OK | W_OK, AT_SYMLINK_NOFOLLOW));
                             ^
copy.c:21:68: error: use of undeclared identifier 'AT_SYMLINK_NOFOLLOW'
    printf("%d\n", faccessat(AT_FDCWD, source, F_OK | R_OK | W_OK, AT_SYMLINK_NOFOLLOW));
                                                                   ^
copy.c:22:30: error: use of undeclared identifier 'AT_FDCWD'
    printf("%d\n", faccessat(AT_FDCWD, dest, F_OK | R_OK | W_OK, AT_SYMLINK_NOFOLLOW));
                             ^
copy.c:22:66: error: use of undeclared identifier 'AT_SYMLINK_NOFOLLOW'
    printf("%d\n", faccessat(AT_FDCWD, dest, F_OK | R_OK | W_OK, AT_SYMLINK_NOFOLLOW));
                                                                 ^
1 warning and 4 errors generated.

解决方法

  • 添加功能测试宏定义:在所有头文件包含之前,添加POSIX或GNU扩展的宏定义,因为Linux glibc中faccessat和AT_*常量需要开启扩展才会在头文件中暴露。修改代码开头:
    #define _POSIX_C_SOURCE 200809L
    // 也可以用#define _GNU_SOURCE
    // SYSTEM INCLUDE FILES
    #include <sys/types.h>
    ...
    
  • 适配编译标准:使用-std=c11编译时,默认不会启用POSIX扩展,必须通过上述宏定义让头文件导出相关函数和常量。
  • 无需调整头文件顺序:只要宏定义正确,fcntl.h就能正常提供所需的常量和函数声明。

原因说明

MacOS的头文件默认会暴露这类POSIX扩展接口,但Linux glibc为了严格遵循C标准,需要显式定义功能测试宏才能解锁这些扩展内容。

内容的提问来源于stack exchange,提问作者Joshua Estes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:15:44