Как предотвратить специфичную для GNU функцию при определении двух источников

#c #gcc #compilation #c-preprocessor #preprocessor

#c #gcc #Сборник #c-препроцессор #препроцессор

Вопрос:

Мне нужно использовать fcntl свойство изменения размера FIFO с помощью F_SETPIPE_SZ . Для этого мне нужно использовать #define _GNU_SOURCE . Однако мой код также включает strerror_r функцию. Обычно я использую его, совместимый с XSI, но когда я добавляю #define _GNU_SOURCE , он автоматически выдает ошибку, по сути, следующую, поскольку он предпочитает использовать GNU strerror_r .

 error: initialization makes integer from pointer without a cast [-Werror=int-conversion]
         int error_num = strerror_r(errno, ERROR_MESSAGE_BUFF, ERROR_MESSAGE_LENGTH);
                         ^~~~~~~~~~
cc1: all warnings being treated as errors
  

По той же причине мне также нужно использовать #define _DEFAULT_SOURCE для других объявлений / определений. Как я могу использовать XSI-совместимый strerror_r вместо этого, когда я использую следующие два

 #define _GNU_SOURCE
#define _DEFAULT_SOURCE
  

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

1. Что вы делаете с выводом ошибок error_num if strerror_r() ? Это, вероятно, повлияет на соответствующий ответ.

2. Возможно, используйте #include <linux/fcntl.h> вместо #define _GNU_SOURCE . Или, может быть, окружить все #include <fcntl.h> #define _GNU_SOURCE и #undef _GNU_SOURCE .

3. @AndrewHenle Пока просто выводит сообщение об ошибке и завершает работу. Но случай может быть изменен, вероятно, в будущем

4. Ну, чтобы сохранить будущую гибкость, я бы подумал, что, вероятно, лучше изолировать любой вызов, который является выбросом из остальной части вашего кода, в его собственном отдельном модуле компиляции и предоставить стандартно-нейтральную оболочку. Поскольку вы заявляете, что большая часть вашего кода совместима с XSI, я бы переместил сам fcntl() вызов GNU в его собственный файл и предоставил что-то вроде gnu_fcntl() функции-оболочки. Это делает совершенно очевидным, что XSI-совместимый код нуждается в специфичной для GNU функции.

5. @IanAbbott не могли бы вы показать последнее использование, о котором вы упоминаете, с небольшим фрагментом кода, пожалуйста?

Ответ №1:

Как я могу использовать XSI-совместимый strerror_r вместо

Создайте отдельный исходный файл с необходимой strerror версией:

 #include <string.h>
int xsi_strerror_r(int errnum, char *buf, size_t buflen) {
   return strerror_r(errnum, buf, buflen);
}
  

Создайте заголовочный файл xsi_strerror.h с объявлением функции:

 #include <stddef.h>
int xsi_strerror_r(int errnum, char *buf, size_t buflen);
  

Затем используйте в своем исходном файле, который использует fcntl , вашу функцию:

 #define _GNU_SOURCE
#include <fcntl.h>
#include "xsi_strerror.h"
int main() {
    if (fcntl(...)) {
        int error_num = xsi_strerror_r(errno, ERROR_MESSAGE_BUFF, ERROR_MESSAGE_LENGTH);
    }
}
  

Скомпилируйте оба файла вместе.