Reputation: 34587
I would like to make the compilation of some files to fail if attempted after a certain date. The reason for this: I found a couple of Y2K38 bugs which I don't have time to fix right now, but would like to make a note of them and I think it would be nice if compilation of the module would just fail after, say, 2020. (I might be insane, but this code is 20 years old I suspect it might survive another 30)
Upvotes: 9
Views: 1712
Reputation: 78953
__DATE__
is not the proper thing for such a goal:
If the date of translation is not available, an implementation-defined valid date shall be supplied.
Any future broken C compiler that still only implements C99 :) and not any of its followers may fix the date to "Jan 1 1970"
or have it wrap once beyond the fatal date in 2038.
Upvotes: 1
Reputation: 75439
Here's a horrible solution:
In your project's general-purpose header directory, run the following (Python) script:
#!/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()
Uncomment the commented-out lines to produce better diagnostic messages.
In the files that need to error after the cutoff date, use this:
#include __DATE__
I dare you to use this in production code.
Upvotes: 5
Reputation: 91209
Instead of dealing with the awkward format of the __DATE__
macro, why not roll your own?
gcc -DTHIS_YEAR=`/bin/date +%Y` yourprogram.c
Then your code can use expressions like #if THIS_YEAR >= 2020
.
Upvotes: 5
Reputation: 6020
A more generic solution that should work with most compilers. It depends a bit on the format of the DATE preprocessor directive
#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
Upvotes: 0
Reputation: 2784
With GCC, you can do something like the following:
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();
}
The way this works is that the error
attribute tells GCC to generate
a compile-time error if any calls to that function are left in the
code after all of GCC's constant-folding, dead-code elimination, and
similar passes have run. Since DATE is a compile-time constant,
GCC can evaluate the if
statement at compile time and remove the
call.
At least one downside is that this depends on GCC's optimization
passes, and so it won't work at gcc -O0
Honestly, you might be better off just adding a runtime check somewhere and failing fast.
Upvotes: 5