использование определения предварительного процессора с прототипом функции - PullRequest
1 голос
/ 03 июля 2019

Мне приходится иметь дело с двумя заголовочными файлами, объявляющими один и тот же прототип с другим именем типа (обратите внимание, что в конце два типа совпадают)

Один из них защищен директивой #ifndef

Я рассматриваю возможность добавления определения, чтобы избежать двойного объявления, но, как мне сказали, не рекомендуется использовать одно и то же имя для определения определения и для имени функции.

acg_header.h

    #ifndef ACos
    /* MATH::ACos/ */
    extern T_Float_user ACos(/* X/ */ T_Float_user X);
    #endif /* ACos */

manual_header.h

    #define ACos // suggested modification
    extern t_float ACos(const t_float X);

Я хотел бы знать, является ли это правильным решением относительно реализации языка Си.

1 Ответ

1 голос
/ 03 июля 2019

Вы можете иметь любое количество совместимых объявлений одной и той же функции или объекта.Нет необходимости или полезно играть в препроцессорные игры, чтобы избежать этой ситуации.Вот почему стандартный подход заключается в том, чтобы каждая функция или глобальная переменная объявлялась в (одном) файле заголовка, и для каждого источника, который обращается или определяет любую функцию или объект для включения соответствующего заголовка.Итак, что касается

, мне приходится иметь дело с двумя заголовочными файлами, объявляющими один и тот же прототип с другим именем типа

, нет, вы не должны приходится иметь дело с этим.Должен быть только один заголовок, объявляющий каждую функцию.Тем не менее, если у вас есть два, и они объявляют функцию совместимым, то у вас все равно не возникает проблем, даже если объявления не совпадают лексически из-за использования различных - но совместимых - псевдонимов типов.

Если декларации в ваших двух заголовочных файлах несовместимы друг с другом, с другой стороны, у вас есть более глубокая проблема.Не более одного из них может быть совместимо с определением функции, и вы не должны использовать никакое другое.

Я подумываю добавить определение, чтобы избежать двойного объявления, но было сказано, что это не очень хорошая практикаиметь одно и то же имя для определения определения и для имени функции.

Опять же, вам лучше всего пропустить все это упражнение, но если вы решите продолжить, то вам нужно понимать, что появленияв вашем коде макро-идентификатор в области будет заменен определением макроса.Таким образом, результат предварительной обработки:

#define ACos // suggested modification
extern t_float ACos(const t_float X);

будет

extern t_float (const t_float X);

, потому что вы определили ACos для развертывания в пустую последовательность.Предварительно обработанный результат недействителен.Если вы должны следовать этому пути, то определите макрос для расширения до его собственного имени:

#define ACos ACos

Затем вы сможете проверить его с помощью директив #ifdef, но вы будетене заставляйте препроцессор искажать вашу программу.Но опять же, на самом деле, не делайте этого вообще.

...