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
相关产品推荐
相关产品推荐

