c препроцессор - сбой при компиляции после определенной даты - PullRequest
9 голосов
/ 02 февраля 2011

Я бы хотел, чтобы компиляция некоторых файлов завершилась неудачно, если попытаться после определенной даты.Причина этого: я нашел пару ошибок Y2K38, которые у меня нет времени на исправление прямо сейчас, но я бы хотел их отметить, и я думаю, что было бы неплохо, если бы компиляция модуля просто не удаласьскажем, 2020. (Я могу быть безумен, но этому коду 20 лет, я подозреваю, что он может выжить еще 30)

Ответы [ 5 ]

5 голосов
/ 02 февраля 2011

Вот ужасное решение:

  1. В каталоге заголовков общего назначения вашего проекта запустите следующий (Python) скрипт:

    #!/usr/bin/python
    
    months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    
    cutoff = 2020
    #safety = 2025
    
    for year in range(2011, cutoff):
        for month in months:
            for day in range(1, 32):
                t = open("%s %2d %d" % (month, day, year), "w")
                t.write("\n");
                t.close()
    
    #for year in range(2011, cutoff):
    #    for month in months:
    #        for day in range(1, 32):
    #            t = open("%s %2d %d" % (month, day, year), "w")
    #            t.write("#error \"Too old\"\n");
    #            t.close()
    

    Раскомментируйте закомментированные строки для получения более качественных диагностических сообщений.

  2. В файлах, в которых требуется ошибка после даты отсечения, используйте это:

    #include __DATE__
    

Смею вас использовать это в рабочем коде.

5 голосов
/ 02 февраля 2011

Вместо того, чтобы работать с неловким форматом макроса __DATE__, почему бы не свернуть свой собственный?

gcc -DTHIS_YEAR=`/bin/date +%Y` yourprogram.c

Тогда ваш код может использовать выражения типа #if THIS_YEAR >= 2020.

5 голосов
/ 02 февраля 2011

С помощью GCC вы можете сделать что-то вроде следующего:

void __attribute__((error("Whoa. It's the future"))) whoa_the_future();

void check_for_the_future() {
    // "Feb  1 2011"
    const char *now = __DATE__;
    if (now[9] >= '2')
        whoa_the_future();
}

Способ работает так, что атрибут error указывает GCC генерировать ошибка времени компиляции, если какие-либо вызовы этой функции остались в код после всех константного свертывания, удаления мертвого кода и аналогичные проходы побежали. Поскольку DATE является константой времени компиляции, GCC может оценить оператор if во время компиляции и удалить позвонить.

По крайней мере, одним недостатком является то, что это зависит от оптимизации GCC проходит, и поэтому он не будет работать на gcc -O0

Честно говоря, вам может быть лучше, просто добавив проверку во время выполнения где-то и быстро терпит неудачу.

1 голос
/ 02 февраля 2011

__DATE__ не подходит для такой цели:

Если дата перевода недоступна, указывается действительная дата, определяемая реализацией.

Любой будущий сломанный компилятор C, который все еще реализует только C99 :), а не любой из его последователей, может зафиксировать дату в "Jan 1 1970" или сделать ее один раз после фатальной даты в 2038 году.

0 голосов
/ 02 февраля 2011

Более общее решение, которое должно работать с большинством компиляторов. Это немного зависит от формата директивы препроцессора DATE

#define DIGIT(ch) (((ch)<'0'||(ch)>'9') ? 0 : ((ch)-'0'))
#define YEAR (1000*DIGIT(__DATE__[7])+100*DIGIT(__DATE__[8])+10*DIGIT(__DATE__[9])+DIGIT(__DATE__[10]))

#ifdef YEAR-2020>0
#error too old
#endif
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...