S_ISDIR и S_ISREG не объявлены, несмотря на включение заголовка

#c #linux #linux-kernel #stat

#c #linux #linux-ядро #статистика

Вопрос:

Я использую «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, amp;s) == 0 )
{
    if( s.st_mode amp; S_ISDIR )
    {
        return false;
    }
    else if( s.st_mode amp; S_ISREG )
    {
        return true;
    }
    else
    {
        return false;
    }
}
else
{
    return false;
}
return false;
  

Комментарии:

1. Ваши сообщения об ошибках относятся к S_ISDIR and S_ISREG , но ваш код использует S_IFDIR and S_IFREG . Пожалуйста, покажите нам код, соответствующий сообщениям об ошибках.

2. @zwol Я изменил код. Извините за это.

Ответ №1:

Вы неправильно используете макросы. Это функциональные макросы, которые принимают режим в качестве параметра:

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

Комментарии:

1. Обратите внимание, что невозможно S_ISDIR(x) S_ISREG(x) одновременно и быть true, поэтому это можно упростить до return !!S_ISREG(s.st_mode) .

Ответ №2:

Возможно, вам интересно, почему ваш исходный код с S_IFREG и S_IFDIR работал в одной операционной системе, а не в другой. Это связано с тем, что S_IFxxx константы являются необязательными в некоторых версиях стандарта POSIX (это стандарт, который определяет содержимое sys/stat.h ).

S_ISxxx Функциональные макросы должны быть доступны, поэтому лучше использовать их, когда есть возможность, но иногда использование S_IFxxx констант может сделать код намного понятнее. Они являются макросами, поэтому вы можете проверить их наличие с #ifdef S_IFREG помощью (если S_IFREG доступно, можно с уверенностью предположить, что и другие тоже).

Некоторые операционные системы не предоставляют S_IFxxx константы по умолчанию, но предоставляют, если вы помещаете #define _XOPEN_SOURCE 700 выше всех своих #include строк. Linux обычно не является одной из этих операционных систем, но она становится одной из этих операционных систем, если вы используете -ansi или -std=cNN в командной строке компилятора. (Примечание. по причинам, слишком сложным для понимания здесь, обычно ошибочно использовать эти переключатели вместо -std=gnuNN .)