2011-01-13 3 views
6

Лучше #define _BSD_SOURCE или установить CPPFLAGS = -D_BSD_SOURCE?Должны ли стандарты указываться в исходном коде или в CPPFLAGS?

Мне кажется, что если часть исходного кода зависит от конкретного стандарта, лучше всего явно указать его в коде с #define. Тем не менее, многие комментарии указывают на то, что определение стандарта на линии компиляции более уместно. Каковы преимущества исключения стандарта из исходного кода и указания его только во время компиляции?

ответ

6

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

При указании определений для всего проекта, а не в отдельных исходных файлах вероятность такого нарушения правила определения правильности сводится к минимуму.

Кроме того, если возникает необходимость добавить новое определение, вы изменяете только один файл makefile, а не все исходные файлы.

+0

Но вы можете использовать разные стандарты для каждой единицы перевода. Если весь проект соответствует C89, за исключением того, что один TU использует расширение gnu, не лучше ли для этого одного файла #define _GNU_SOURCE, чем для того, чтобы испортить весь проект? Таким образом, если я использую функцию, которая зависит от более современного стандарта, чем C89 в некоторых других TU, но я не знаю об этой уверенности, я буду знать об этом во время компиляции. Если весь проект зависит от современного стандарта, это затрудняет удаление зависимости. –

+0

Должен признаться, я никогда не смешивал и не сопоставлял источники, требующие разных стандартов (или препроцессора) в одном двоичном формате. Если бы я это сделал, я бы все же указал флаги для этого конкретного источника в make-файле (как целевые переменные) просто потому, что все мои флаги компилятора находятся в одном месте в make-файле. Более того, я часто компилирую свои источники с разными компиляторами (g ++, SunCC) на разных платформах, поэтому это специфичный для платформы make-файл, который является подходящим местом для определения специфических для платформы определений. –

+1

@ Виллиам: проблема в том, что если вы пытаетесь смешивать разные стандарты в разных единицах перевода, нет никакой гарантии, что вы можете безопасно связать полученные объекты в один исполняемый файл. Он может работать или может быть неудачным, или может показаться, что он работает, но дает вам тонкие, жесткие задачи диагностики во время выполнения. –