尽管包含 <sys/stat.h> header,但 S_ISDIR 和 S_ISREG 未声明

S_ISDIR and S_ISREG undeclared despite including the <sys/stat.h> header

我正在使用“S_ISDIR”和“S_ISREG”,但收到未声明的错误。我尝试在 macOS 中使用它(使用 S_IFDIR 和 S_IFREG)并且它有效但在 linux 终端中无效。

error: ‘S_ISDIR’ undeclared (first use in this function)  
error: ‘S_ISREG’ undeclared (first use in this function); did you mean ‘S_ISDIR’?  
struct stat s;
if(stat(fileName, &s) == 0 )
{
    if( s.st_mode & S_ISDIR )
    {
        return false;
    }
    else if( s.st_mode & S_ISREG )
    {
        return true;
    }
    else
    {
        return false;
    }
}
else
{
    return false;
}
return false;

您使用的宏不正确。它们是 function-like 接受模式作为参数的宏:

if( S_ISDIR(s.st_mode) )
{
    return false;
}
else if( S_ISREG(s.st_mode) )
{
    return true;
}
else
{
    return false;
}

您可能想知道为什么带有 S_IFREGS_IFDIR 的原始代码可以在一个操作系统上运行,但不能在另一个操作系统上运行。这是因为 S_IFxxx 常量在 POSIX 标准的某些修订版中是可选的(这是指定 sys/stat.h 内容的标准)。

S_ISxxx function-like 宏是必须可用的,因此最好尽可能使用它们,但有时使用 S_IFxxx 常量可以使代码更清晰。它们是宏,因此您可以使用 #ifdef S_IFREG 测试它们的存在(如果 S_IFREG 可用,则可以安全地假设其他宏也可用)。

某些操作系统默认不提供 S_IFxxx 常量,但如果您将 #define _XOPEN_SOURCE 700 放在所有 #include 行的上方,则会提供。 Linux 不是 通常 这些操作系统之一,但如果您在编译器命令上使用 -ansi-std=cNN 它会成为这些操作系统之一线。 (N.B。由于太复杂的原因无法进入这里,使用这些开关而不是 -std=gnuNN 通常是错误的。)