2014-10-20 2 views
2

я искать способ, чтобы напечатать сообщение или сломать прогон компиляции, если headerfile истекло, что-то вроде:Как раз состояние во время компиляции

#ifndef somemagic(__DATE__ , "2014") 
#pragma message("ALARM! Someone should check this file!") 
#endif 

или есть какая-то новый шаблон магия?

Чтобы быть более конкретным. Мне не удалось изменить цепочку компилятора. Решение должно быть частью исходного кода. Переключатель компилятора или даже добавить определение в make-файл не является опцией.

Примечание: Это технический вопрос, который (IMHO) заслуживает технического ответа. Даже если это может не соответствовать любой ситуации, есть причины, по которым такая техника может быть удобной.

+0

Я не уверен, что это хорошая вещь, чтобы сделать. Если вы действительно хотели этого с GCC, вы можете расширить его с помощью [MELT] (http://gcc-melt.org/) –

+1

Но я действительно думаю, что вы ошибаетесь в этом. Кто-то может захотеть в 2016 году скомпилировать исходный код версии 11 сентября 2014 года с законными основаниями. В то время вы, возможно, даже не работали в одном месте! –

ответ

4

Вы можете использовать тот факт, что __DATE__ расширяющиеся в строку буквальной и строковые литералы являются постоянными выражениями:

static_assert(
    (1000 * (__DATE__[7] - '0') 
    + 100 * (__DATE__[8] - '0') 
    + 10 * (__DATE__[9] - '0') 
    +  (__DATE__[10] - '0') 
) != 2014, "It's 2014!" 
); 

Live example

+0

Это почти хит :-) К сожалению, VS2013 дает мне ошибку C2057 «ожидаемое постоянное выражение». Еще не проверял его. –

+1

@MartinSchlott [Работает с clang] (http://coliru.stacked-crooked.com/a/b8414ca0e1861c7e).Я бы заподозрил ошибку VS2013 - они даже не реализуют 'constexpr', поэтому их общая поддержка константных выражений также может быть ограничена. – Angew

+0

Похоже, вы правы. static_assert не может оценить постоянную строку. Выглядит также как ошибка для меня тоже. –

2

Простейшим способом может быть изменение строительной техники для компиляции, например. -DCURRENT_BUILD_YEAR=2014. В Linux с Makefile вы могли бы добавить в него:

CPPFLAGS += -DCURRENT_BUILD_YEAR=$(shell date +%Y) 

Тогда код что-то вроде

#if CURRENT_BUILD_YEAR > 2014 
#error someone should look at this 
#endif 

Однако, как я заметил, что это плохая вещь, чтобы сделать ИМХО. Возможно, использование крюка контроля версий может быть более актуальным.

Если вы настаиваете делать это в компиляторе (который я считаю, это неправильный подход), с помощью GCC рассмотреть вопрос о расширении его MELT

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

BTW, вдохновляясь Angew's answer, вы могли бы, возможно, попробовать:

#define CURRENT_BUILD_YEAR (1000 * (__DATE__[7] - '0') \ 
           + 100 * (__DATE__[8] - '0') \ 
           + 10 * (__DATE__[9] - '0') \ 
           +  (__DATE__[10] - '0')) 

, но я предполагаю, что это, вероятно, не будет работать, потому что я не думаю, что препроцессор должен знать о [] индекс во время компиляции.

+0

«Меняйте свою строительную технику». Заголовок является частью процесса, который я не могу изменить. Я расширил свой вопрос. –

+0

Я имел в виду изменение вашего файла Makefile. –

+0

Ницца, но нет. Как вы уже упоминали, препроцессор не любит строку после #if. Пробовал это с помощью XCode (Clang) и VS2013. Но thx. –

Смежные вопросы