Discussion:
How to fix warning: [-Wdate-time]
Add Reply
MehdiAmini
2017-04-13 10:14:02 UTC
Reply
Permalink
Raw Message
Hi,
I tried to improve upon my_err function, but I get two warnings:

#define BUFF_SIZE 256
#define my_err(...) \
do { \
char buff[BUFF_SIZE]; \
fprintf(stderr,"\n"); \
snprintf(buff, sizeof(buff),__FILE__); \
fprintf(stderr,"FILE:"); \
fprintf(stderr,"%s\n" ,buff); \
snprintf(buff, sizeof(buff),__FUNCTION__); \
fprintf(stderr,"FUNCTION:"); \
fprintf(stderr,"%s\n" ,buff); \
fprintf(stderr,"LINE:%d\n",__LINE__); \
snprintf(buff, sizeof(buff),__VA_ARGS__); \
my_err_s(buff); \
} while (0)


noreturn void my_err_s(const char * const s)
{
if ((s == NULL) || (*s == '\0'))
{
fprintf(stderr, "Please provide a proper message for "
"my_err function.\n");
exit(EXIT_FAILURE);
}

fprintf(stderr,"DATE:%s\n",__DATE__);
fprintf(stderr,"TIME:%s\n",__TIME__);

fprintf(stderr, "\nERROR:%s\n", s);
exit(EXIT_FAILURE);
}

warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"DATE:%s\n",__DATE__);
^

warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"TIME:%s\n",__TIME__);
^

What to do to fix the warnings?
--
www.my-c-codes.com/

Farewell.
Barry Schwarz
2017-04-13 12:28:18 UTC
Reply
Permalink
Raw Message
Post by MehdiAmini
Hi,
#define BUFF_SIZE 256
#define my_err(...) \
do { \
char buff[BUFF_SIZE]; \
fprintf(stderr,"\n"); \
snprintf(buff, sizeof(buff),__FILE__); \
fprintf(stderr,"FILE:"); \
fprintf(stderr,"%s\n" ,buff); \
Why do you use three function calls and an unnecessary buffer when the
simpler and easier to read equivalent
fprintf(stderr, "FILE:%s\n", __FILE__);
is available?

Additionally, on some systems, the file name can contain the '%'
character. If it does so, then statements of the form
snprintf(buff, sizeof(buff),__FILE__);
can cause undefined behavior. When attempting to print a string over
whose content you have no control, using
snprintf(buff, sizeof(buff),"%s",__FILE__);
will avoid the potential undefined behavior.

<snip>
Post by MehdiAmini
fprintf(stderr,"DATE:%s\n",__DATE__);
fprintf(stderr,"TIME:%s\n",__TIME__);
fprintf(stderr, "\nERROR:%s\n", s);
exit(EXIT_FAILURE);
}
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"DATE:%s\n",__DATE__);
^
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"TIME:%s\n",__TIME__);
^
What to do to fix the warnings?
This warning is an optional feature of your compiler. If you do not
want it, you should not specify the option that activates it.
Alternately, you could specify the option that deactivates it. How to
perform either action is a discussion for a group where your compiler
is topical. This has nothing to do with the C language itself.
--
Remove del for email
MehdiAmini
2017-04-14 08:25:05 UTC
Reply
Permalink
Raw Message
[...]
Post by Barry Schwarz
Post by MehdiAmini
What to do to fix the warnings?
This warning is an optional feature of your compiler. If you do not
want it, you should not specify the option that activates it.
Alternately, you could specify the option that deactivates it. How to
perform either action is a discussion for a group where your compiler
is topical. This has nothing to do with the C language itself.
For my Clang compiler, three #pragma did the job to deactivate it in a
certain place.
--
www.my-c-codes.com/

Farewell.
Keith Thompson
2017-04-14 15:50:59 UTC
Reply
Permalink
Raw Message
Post by MehdiAmini
[...]
Post by Barry Schwarz
Post by MehdiAmini
What to do to fix the warnings?
This warning is an optional feature of your compiler. If you do not
want it, you should not specify the option that activates it.
Alternately, you could specify the option that deactivates it. How to
perform either action is a discussion for a group where your compiler
is topical. This has nothing to do with the C language itself.
For my Clang compiler, three #pragma did the job to deactivate it in a
certain place.
What #pragma?

Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Ken Brody
2017-04-14 17:42:59 UTC
Reply
Permalink
Raw Message
Post by Keith Thompson
Post by MehdiAmini
[...]
Post by Barry Schwarz
Post by MehdiAmini
What to do to fix the warnings?
This warning is an optional feature of your compiler. If you do not
want it, you should not specify the option that activates it.
Alternately, you could specify the option that deactivates it. How to
perform either action is a discussion for a group where your compiler
is topical. This has nothing to do with the C language itself.
For my Clang compiler, three #pragma did the job to deactivate it in a
certain place.
What #pragma?
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
Sometimes you only want to disable a warning for a particular piece of code.
Why force an entire project to be compiled with "-Wno-date-time" for one
macro?
--
Kenneth Brody
James Kuyper
2017-04-14 18:26:11 UTC
Reply
Permalink
Raw Message
...
Post by Ken Brody
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
Sometimes you only want to disable a warning for a particular piece of code.
Why force an entire project to be compiled with "-Wno-date-time" for one
macro?
Because the entire project is one for which the motivations for that
warning don't apply? It is really a rather obscure issue to be warning
about.
David Brown
2017-04-17 14:26:30 UTC
Reply
Permalink
Raw Message
Post by James Kuyper
...
Post by Ken Brody
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
Sometimes you only want to disable a warning for a particular piece of code.
Why force an entire project to be compiled with "-Wno-date-time" for one
macro?
Because the entire project is one for which the motivations for that
warning don't apply? It is really a rather obscure issue to be warning
about.
IMHO, it is a very good thing to be warning about. If your program
contains the macros __DATA__ or __TIME__, then your builds are not
reproducible. I cannot think of any other way to make a build
non-deterministic, at least on compilers I have used.

That means that as long as you avoid these macros, you can use the
generated binary file as a way to check that you have exactly the same
build as on a previous occasion. If you are working on software where
you need to check or qualify your builds in a particular manner, this is
essential.

So my thoughts about how to "fix" this warning is simply to avoid using
__DATE__ or __TIME__.
James R. Kuyper
2017-04-17 14:52:39 UTC
Reply
Permalink
Raw Message
...
Post by David Brown
Post by James Kuyper
Post by Ken Brody
Why force an entire project to be compiled with "-Wno-date-time" for one
macro?
Because the entire project is one for which the motivations for that
warning don't apply? It is really a rather obscure issue to be warning
about.
IMHO, it is a very good thing to be warning about. If your program
contains the macros __DATA__ or __TIME__, then your builds are not
reproducible. I cannot think of any other way to make a build
non-deterministic, at least on compilers I have used.
That means that as long as you avoid these macros, you can use the
generated binary file as a way to check that you have exactly the same
build as on a previous occasion.
That's not a particularly useful thing to test with most of the software
I work on. As a general rule, if I'm compiling the code, something has
changed: the source code, one of the libraries it's connected to, the
compiler itself, or the operating system. The normal expectation is that
the generated binary file is NOT the same as any previously created.
In fact, in the past, we've used a version control system which included
a specialized variant of "make" which automatically checked whether all
files opened during a previous build of an object file (including all
#include files (recursively) and the compiler itself) still have the
same version they had during that build, and that all environment
variables have the same values they had during the previous build. If
so, it would restore a copy of the object file created by that previous
build, rather than rebuilding it. The object files themselves had
versions, and the same logic was used when linking them together in an
executable. We're not using that system anymore, but not because of that
feature - we found it rather convenient

One of the first things several of my programs do when executed is put a
message in the status log containing the version number of the file that
contains the code which caused that message to be printed, along with
the current values of __DATE__ and __TIME__. I've found that information
to be fairly useful; more useful than knowing whether the object files
were identical to those created by a previous build.
David Brown
2017-04-17 18:00:10 UTC
Reply
Permalink
Raw Message
Post by James R. Kuyper
...
Post by David Brown
Post by James Kuyper
Post by Ken Brody
Why force an entire project to be compiled with "-Wno-date-time" for one
macro?
Because the entire project is one for which the motivations for that
warning don't apply? It is really a rather obscure issue to be warning
about.
IMHO, it is a very good thing to be warning about. If your program
contains the macros __DATA__ or __TIME__, then your builds are not
reproducible. I cannot think of any other way to make a build
non-deterministic, at least on compilers I have used.
That means that as long as you avoid these macros, you can use the
generated binary file as a way to check that you have exactly the same
build as on a previous occasion.
That's not a particularly useful thing to test with most of the software
I work on. As a general rule, if I'm compiling the code, something has
changed: the source code, one of the libraries it's connected to, the
compiler itself, or the operating system. The normal expectation is that
the generated binary file is NOT the same as any previously created.
In fact, in the past, we've used a version control system which included
a specialized variant of "make" which automatically checked whether all
files opened during a previous build of an object file (including all
#include files (recursively) and the compiler itself) still have the
same version they had during that build, and that all environment
variables have the same values they had during the previous build. If
so, it would restore a copy of the object file created by that previous
build, rather than rebuilding it. The object files themselves had
versions, and the same logic was used when linking them together in an
executable. We're not using that system anymore, but not because of that
feature - we found it rather convenient
One of the first things several of my programs do when executed is put a
message in the status log containing the version number of the file that
contains the code which caused that message to be printed, along with
the current values of __DATE__ and __TIME__. I've found that information
to be fairly useful; more useful than knowing whether the object files
were identical to those created by a previous build.
The requirements for this sort of thing vary greatly - for some kinds of
development work, __DATE__ and __TIME__ are /exactly/ what you need.
For others, they are exactly what you /don't/ need.

So it is good for a compiler to have such a warning - and good that the
warning is entirely optional!
Keith Thompson
2017-04-17 15:08:17 UTC
Reply
Permalink
Raw Message
Post by David Brown
Post by James Kuyper
...
Post by Ken Brody
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
Sometimes you only want to disable a warning for a particular piece of code.
Why force an entire project to be compiled with "-Wno-date-time" for one
macro?
Because the entire project is one for which the motivations for that
warning don't apply? It is really a rather obscure issue to be warning
about.
IMHO, it is a very good thing to be warning about. If your program
contains the macros __DATA__ or __TIME__, then your builds are not
reproducible. I cannot think of any other way to make a build
non-deterministic, at least on compilers I have used.
That means that as long as you avoid these macros, you can use the
generated binary file as a way to check that you have exactly the same
build as on a previous occasion. If you are working on software where
you need to check or qualify your builds in a particular manner, this is
essential.
So my thoughts about how to "fix" this warning is simply to avoid using
__DATE__ or __TIME__.
Sure, the -Wdate-date option is useful if you need reproducible builds.
But if you're using __DATE__ and __TIME__, then you apparently *don't*
need reproducible builds.

The OP, Mehdi Amini, seems to want to use both -Wdate-time and
__DATE__/__TIME__, and is looking for (and has found) a way to turn off
the effect of -Wdate-time for just one source file. That seems frankly
silly.

I can imagine using -Wdate-time by default and comparing object files,
and then making an exception for the one source file that uses __DATE__
and __TIME__, but the Mehdi's only stated rationale for using
-Wdate-time is that "IMHO this warning exists for a reason".
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
David Brown
2017-04-17 18:04:35 UTC
Reply
Permalink
Raw Message
Post by Keith Thompson
Post by David Brown
Post by James Kuyper
...
Post by Ken Brody
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
Sometimes you only want to disable a warning for a particular piece of code.
Why force an entire project to be compiled with "-Wno-date-time" for one
macro?
Because the entire project is one for which the motivations for that
warning don't apply? It is really a rather obscure issue to be warning
about.
IMHO, it is a very good thing to be warning about. If your program
contains the macros __DATA__ or __TIME__, then your builds are not
reproducible. I cannot think of any other way to make a build
non-deterministic, at least on compilers I have used.
That means that as long as you avoid these macros, you can use the
generated binary file as a way to check that you have exactly the same
build as on a previous occasion. If you are working on software where
you need to check or qualify your builds in a particular manner, this is
essential.
So my thoughts about how to "fix" this warning is simply to avoid using
__DATE__ or __TIME__.
Sure, the -Wdate-date option is useful if you need reproducible builds.
But if you're using __DATE__ and __TIME__, then you apparently *don't*
need reproducible builds.
Yes - or you are using the macros without considering the repercussions
for reproducible builds. Whatever the OP was thinking originally, I
hope that by now he knows the pros and cons of using the macros, and can
make an informed decision.
Post by Keith Thompson
The OP, Mehdi Amini, seems to want to use both -Wdate-time and
__DATE__/__TIME__, and is looking for (and has found) a way to turn off
the effect of -Wdate-time for just one source file. That seems frankly
silly.
It might be reasonable to have __DATE__ and __TIME__ as part of code
that is conditionally compiled in debug or development builds, and
disabled at a later date. In such circumstances, you may then want to
allow the macros in a piece of code that you know will be disabled
before "real" builds.
Post by Keith Thompson
I can imagine using -Wdate-time by default and comparing object files,
and then making an exception for the one source file that uses __DATE__
and __TIME__, but the Mehdi's only stated rationale for using
-Wdate-time is that "IMHO this warning exists for a reason".
Presumably he now understands this reason, and can decide what he wants
to do about it.
Mehdi Amini
2017-04-15 03:20:02 UTC
Reply
Permalink
Raw Message
[...]
Post by Keith Thompson
Post by MehdiAmini
For my Clang compiler, three #pragma did the job to deactivate it in a
certain place.
What #pragma?
See:
http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas

My code:
noreturn void my_err_s(const char * const s)
{
if ((s == NULL) || (*s == '\0'))
{
fprintf(stderr, "Please provide a proper message for "
"my_err function.\n");
exit(EXIT_FAILURE);
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdate-time"

fprintf(stderr,"DATE:%s\n",__DATE__);
fprintf(stderr,"TIME:%s\n",__TIME__);

#pragma clang diagnostic pop

fprintf(stderr, "\nERROR:%s\n", s);
exit(EXIT_FAILURE);
}
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
IMHO this warning exists for a reason, so I just disable it for this
part only.
--
www.my-c-codes.com/

Farewell.
Keith Thompson
2017-04-15 22:05:37 UTC
Reply
Permalink
Raw Message
[...]
Post by Mehdi Amini
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
IMHO this warning exists for a reason, so I just disable it for this
part only.
Of course it exists for a reason, but why assume that that reason
applies to you? If you need bitwise identical output from your
compiler, then the -Wdate-time option is one way to enforce that --
but if you're using __DATE__ and __TIME__ in your code, then you
obviously *don't* need bitwise identical output. Why on Earth
would you use a compile-time option that enforces something you
don't need -- and then use an compiler-specific macro to override it?

The __DATE__ and __TIME__ macros also exist for a reason.

If you had a reason to use -Wdate-time for most of your code, then using
the #pragma would make sense, but based on what you've said that doesn't
seem to be the case.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Ken Brody
2017-04-17 15:42:30 UTC
Reply
Permalink
Raw Message
Post by Keith Thompson
[...]
Post by Mehdi Amini
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
IMHO this warning exists for a reason, so I just disable it for this
part only.
Of course it exists for a reason, but why assume that that reason
applies to you? If you need bitwise identical output from your
compiler, then the -Wdate-time option is one way to enforce that --
but if you're using __DATE__ and __TIME__ in your code, then you
obviously *don't* need bitwise identical output. Why on Earth
would you use a compile-time option that enforces something you
don't need -- and then use an compiler-specific macro to override it?
The __DATE__ and __TIME__ macros also exist for a reason.
If you had a reason to use -Wdate-time for most of your code, then using
the #pragma would make sense, but based on what you've said that doesn't
seem to be the case.
I see two ways to look at this situation:

(1) "I know that this will trigger the date/time warning if it's enabled,
so I'll wrap my code with pragmas to turn it off for my section of the code,
because it's an innocuous warning."

and

(2) "If the code is being compiled with that warning enabled, then who am I
to say it's innocuous? The user turned it on for a reason, and the warning
should be generated as expected."


Okay, I can see a third way to look at this...


(3) "I really don't know what the user wants, so I'll wrap the pragmas in
#if statements, and put a large comment block at the top explaining the
situation, and says 'if you are running with the date/time warning enabled,
but don't care about it for this section of the code, then change the
#define to 1, otherwise leave it at zero', so the user can have control over
it."
--
Kenneth Brody
s***@casperkitty.com
2017-04-17 15:55:00 UTC
Reply
Permalink
Raw Message
Post by Ken Brody
(1) "I know that this will trigger the date/time warning if it's enabled,
so I'll wrap my code with pragmas to turn it off for my section of the code,
because it's an innocuous warning."
and
(2) "If the code is being compiled with that warning enabled, then who am I
to say it's innocuous? The user turned it on for a reason, and the warning
should be generated as expected."
A third possibility would be "The tool I'm using to check binary equivalence
can be told to ignore a certain part of the file, and I want to use the
__DATE__ and __TIME__ macros to initialized some objects that I've forced
into that part of the file, but I want the compiler to squawk if the macros
are used anywhere else."
James R. Kuyper
2017-04-17 15:57:29 UTC
Reply
Permalink
Raw Message
Post by Ken Brody
Post by Keith Thompson
[...]
Post by Mehdi Amini
Post by Keith Thompson
Why can't you just invoke the compiler without the "-Wdate-time" option,
or with "-Wno-date-time"?
IMHO this warning exists for a reason, so I just disable it for this
part only.
Of course it exists for a reason, but why assume that that reason
applies to you? If you need bitwise identical output from your
compiler, then the -Wdate-time option is one way to enforce that --
but if you're using __DATE__ and __TIME__ in your code, then you
obviously *don't* need bitwise identical output. Why on Earth
would you use a compile-time option that enforces something you
don't need -- and then use an compiler-specific macro to override it?
The __DATE__ and __TIME__ macros also exist for a reason.
If you had a reason to use -Wdate-time for most of your code, then using
the #pragma would make sense, but based on what you've said that doesn't
seem to be the case.
(1) "I know that this will trigger the date/time warning if it's enabled,
so I'll wrap my code with pragmas to turn it off for my section of the code,
because it's an innocuous warning."
and
(2) "If the code is being compiled with that warning enabled, then who am I
to say it's innocuous? The user turned it on for a reason, and the warning
should be generated as expected."
Okay, I can see a third way to look at this...
(3) "I really don't know what the user wants, so I'll wrap the pragmas in
#if statements, and put a large comment block at the top explaining the
situation, and says 'if you are running with the date/time warning enabled,
but don't care about it for this section of the code, then change the
#define to 1, otherwise leave it at zero', so the user can have control over
it."
I see a third way of looking at this, which seems to be the one used by
the OP: "I have no idea what the purpose of this warning is, but since
it exists, I've decided to turn it on. The warning has triggered for
this particular piece of code, and there's nothing really wrong with it,
so I'll use #pragmas to turn the warning off in this particular case."

Either you have a good reason for wanting that warning turned on, in
which case you should remove the use of __DATE__ and __TIME__ from that
code, or you have a good reason for using __DATE__ and __TIME__, in
which case you should turn off that warning for the entire program.
Kenny McCormack
2017-04-13 13:09:38 UTC
Reply
Permalink
Raw Message
In article <ocnirh$pu4$***@dont-email.me>,
MehdiAmini <***@gmail.com> wrote:
...
Post by MehdiAmini
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"DATE:%s\n",__DATE__);
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"TIME:%s\n",__TIME__);
What to do to fix the warnings?
Barry has given you the answer - if you don't want these warnings, then do
whatever's necessary to inhibit the warnings.

But I think what you're really asking is "What does this warning mean?"
and I have to admit that I was puzzled as well. However, "man gcc" shows:

-Wdate-time
Warn when macros "__TIME__", "__DATE__" or "__TIMESTAMP__" are
encountered as they might prevent bit-wise-identical reproducible
compilations.

which seems pretty pedantic to me. I doubt anyone really cares about this.

And, to expand on that comment, I've generally found that compilation is
not entirely deterministic - which is to say that I've never relied upon,
nor have I ever assumed, nor have I ever expected to be able to assume or
to rely upon the results of one compilation to be bitwise identical to the
results of any other compilation (even though all inputs and conditions are
otherwise identical).

So, it all seems kind of hinky to me.
--
Watching ConservaLoons playing with statistics and facts is like watching a
newborn play with a computer. Endlessly amusing, but totally unproductive.
j***@gmail.com
2017-04-13 13:27:38 UTC
Reply
Permalink
Raw Message
Post by Kenny McCormack
...
Post by MehdiAmini
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"DATE:%s\n",__DATE__);
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"TIME:%s\n",__TIME__);
What to do to fix the warnings?
Barry has given you the answer - if you don't want these warnings, then do
whatever's necessary to inhibit the warnings.
But I think what you're really asking is "What does this warning mean?"
-Wdate-time
Warn when macros "__TIME__", "__DATE__" or "__TIMESTAMP__" are
encountered as they might prevent bit-wise-identical reproducible
compilations.
which seems pretty pedantic to me. I doubt anyone really cares about this.
And, to expand on that comment, I've generally found that compilation is
not entirely deterministic - which is to say that I've never relied upon,
nor have I ever assumed, nor have I ever expected to be able to assume or
to rely upon the results of one compilation to be bitwise identical to the
results of any other compilation (even though all inputs and conditions are
otherwise identical).
So, it all seems kind of hinky to me.
It can be important when one group absorbs the code from another group,
and they need to have a build process that produces exact binaries. This
can happen in the government where contractors that develop software for a
government program, and then the contract is up and the government takes
over development and maintenance.

Often binary equivalence is desired when software accreditation is done,
like safe for flight or when other regulatory testing is required. This
is quite expensive, so being able to reproduce exact binaries implies that
if your software is made out of many modules, and you change the source
in such a way that only part of your modules have a binary difference, then
there's no need to put the executables that weren't binary altered through
the expensive testing process. This is also how one can get stuck using a
*really* old compiler.

Best regards,
John D.
s***@casperkitty.com
2017-04-15 15:56:07 UTC
Reply
Permalink
Raw Message
Post by j***@gmail.com
It can be important when one group absorbs the code from another group,
and they need to have a build process that produces exact binaries. This
can happen in the government where contractors that develop software for a
government program, and then the contract is up and the government takes
over development and maintenance.
Out of curiosity, would there be any problem with a compiler allowing a
programmer to use command-line options like:

-d__DATE__=\"Jan 01 1980\" -d__TIME__=\"00:00:00\"

to override the default definitions of those macros? Or else having the
macros expand in a way which would be guaranteed to produce a diagnostic?
Keith Thompson
2017-04-15 22:01:57 UTC
Reply
Permalink
Raw Message
Post by s***@casperkitty.com
Post by j***@gmail.com
It can be important when one group absorbs the code from another group,
and they need to have a build process that produces exact binaries. This
can happen in the government where contractors that develop software for a
government program, and then the contract is up and the government takes
over development and maintenance.
Out of curiosity, would there be any problem with a compiler allowing a
-d__DATE__=\"Jan 01 1980\" -d__TIME__=\"00:00:00\"
to override the default definitions of those macros? Or else having the
macros expand in a way which would be guaranteed to produce a diagnostic?
The problem would be that the expansions of __DATE__ and __TIME__ would
be whatever was passed on the compiler command line and not, as the
standard specifies and a reader will assume, the date and time of
translation.

On the other hand, compilers *are* allowed to do that (the option is
typically "-D" rather than "-d", and the quoting needs to be fixed if
that's supposed to be part of a shell command line). The standard
(6.10.8p2) says that none of the predefined macro names shall be the
subject of #define or #undef, but that's not a constraint, so it is at
most undefined behavior -- and the standard doesn't talk about -D.
gcc prints a warning and allows it.

On the other other hand, you could always use a different name, perhaps

-D__TRANSLATION_TIME__=...

(I was going to suggest __TIMESTAMP__, but that's already a gcc
extension.)
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
s***@casperkitty.com
2017-04-16 18:44:58 UTC
Reply
Permalink
Raw Message
Post by Keith Thompson
The problem would be that the expansions of __DATE__ and __TIME__ would
be whatever was passed on the compiler command line and not, as the
standard specifies and a reader will assume, the date and time of
translation.
The Standard does not require any particular degree of precision, nor does
it specify the means via which an implementation would determine the time.
There is no requirement that platforms which host C compilers need to have
any kind of real-time clock functionality. If a compiler included a
command-line option to say "Don't trust the system clock--the time is
actually 1989-06-05 04:32:10, I don't think the Standard would require that
the compiler not believe the command line.

Further, in the event that a project happens to be built in multiple steps
that occur days apart, I don't think the Standard specifies which moment in
the build process should be identified by __DATE__ and __TIME__. I would
think a conforming implementation could defer the evaluation of those
strings to build time (the compiler would have to supply place-holder text
and specify everyplace where that text appears within objects' initial
values, but designing that feature into a compiler and linker would not be
difficult).
Post by Keith Thompson
On the other hand, compilers *are* allowed to do that (the option is
typically "-D" rather than "-d", and the quoting needs to be fixed if
that's supposed to be part of a shell command line). The standard
(6.10.8p2) says that none of the predefined macro names shall be the
subject of #define or #undef, but that's not a constraint, so it is at
most undefined behavior -- and the standard doesn't talk about -D.
gcc prints a warning and allows it.
It is generally accepted that command-line options may direct a conforming
compiler to behave in non-conforming fashion; if a compiler defines __DATE__
and __TIME__ before processing -D, and allows the latter definitions to
override the former, that would yield the indicated behavior without the
compiler having to provide any specialized feature to override the build
date and time.
Post by Keith Thompson
On the other other hand, you could always use a different name, perhaps
-D__TRANSLATION_TIME__=...
(I was going to suggest __TIMESTAMP__, but that's already a gcc
extension.)
There are a variety of ways of handling things. If one is using code that
is maintained by someone else and happens to use __DATE__ and __TIME__,
being able to override those without having to edit the source file could
be advantageous, since project management can be easier if imported files
precisely match versions maintained elsewhere.
Keith Thompson
2017-04-16 20:45:30 UTC
Reply
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Keith Thompson
The problem would be that the expansions of __DATE__ and __TIME__ would
be whatever was passed on the compiler command line and not, as the
standard specifies and a reader will assume, the date and time of
translation.
The Standard does not require any particular degree of precision, nor does
it specify the means via which an implementation would determine the time.
There is no requirement that platforms which host C compilers need to have
any kind of real-time clock functionality. If a compiler included a
command-line option to say "Don't trust the system clock--the time is
actually 1989-06-05 04:32:10, I don't think the Standard would require that
the compiler not believe the command line.
Did you check what the standard actually says? For __DATE__,
it says that "If the date of translation is not available, an
implementation-defined valid date shall be supplied.", and similarly
for __TIME__.
Post by s***@casperkitty.com
Further, in the event that a project happens to be built in multiple steps
that occur days apart, I don't think the Standard specifies which moment in
the build process should be identified by __DATE__ and __TIME__. I would
think a conforming implementation could defer the evaluation of those
strings to build time (the compiler would have to supply place-holder text
and specify everyplace where that text appears within objects' initial
values, but designing that feature into a compiler and linker would not be
difficult).
It's "the date [or time] of translation of the preprocessing translation
unit", which implies that it's when translation phase 4 is executed
(that's when macros are expanded). Of course it can differ for
different source files within a project.

[...]
Post by s***@casperkitty.com
It is generally accepted that command-line options may direct a conforming
compiler to behave in non-conforming fashion; if a compiler defines __DATE__
and __TIME__ before processing -D, and allows the latter definitions to
override the former, that would yield the indicated behavior without the
compiler having to provide any specialized feature to override the build
date and time.
It is generally accepted that command-line options can cause a
conforming implementation to be non-conforming.

"gcc -std=c11 -pedantic" is (let's assume) conforming.
"gcc -std=c11 -pedantic -D__DATE__=42" is not.

[...]
Post by s***@casperkitty.com
There are a variety of ways of handling things. If one is using code that
is maintained by someone else and happens to use __DATE__ and __TIME__,
being able to override those without having to edit the source file could
be advantageous, since project management can be easier if imported files
precisely match versions maintained elsewhere.
Presumably that code uses __DATE__ and __TIME__ for a reason. Sure, you
can do things to break that usage.

You're jumping through multiple hoops looking for ways to violate the
requirements imposed by the standard. Some of those ways might manage
to avoid violating the letter of the standard.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Ken Brody
2017-04-17 16:14:32 UTC
Reply
Permalink
Raw Message
On 4/16/2017 4:45 PM, Keith Thompson wrote:
[...]
Post by Keith Thompson
It's "the date [or time] of translation of the preprocessing translation
unit", which implies that it's when translation phase 4 is executed
(that's when macros are expanded). Of course it can differ for
different source files within a project.
[...]

But, is that the *start* time, the *end* time, or the *current* time when
the preprocessor hits the "__TIME__" reference? (As I previously mentioned,
what happens if the system clock changes between the time it sees the
reference in line 1 and the time it sees the reference in line 1000?
--
Kenneth Brody
Ken Brody
2017-04-17 16:06:14 UTC
Reply
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Keith Thompson
The problem would be that the expansions of __DATE__ and __TIME__ would
be whatever was passed on the compiler command line and not, as the
standard specifies and a reader will assume, the date and time of
translation.
The Standard does not require any particular degree of precision, nor does
it specify the means via which an implementation would determine the time.
There is no requirement that platforms which host C compilers need to have
any kind of real-time clock functionality. If a compiler included a
command-line option to say "Don't trust the system clock--the time is
actually 1989-06-05 04:32:10, I don't think the Standard would require that
the compiler not believe the command line.
NB: I am in no way a "language lawyer".

Looking at N1256 (yes, I know it's not the latest, but it's the latest I
have on this computer), section 6.10.8 says this about __DATE__:

"If the date of translation is not available, an implementation-defined
valid date shall be supplied."

A similar statement is made about __TIME__.

Without a detailed explanation of what "is not available" means, you could
easily say that "using compiler flag X will cause the compiler to behave as
if the date and time are not available" is still conforming.
Post by s***@casperkitty.com
Further, in the event that a project happens to be built in multiple steps
that occur days apart, I don't think the Standard specifies which moment in
the build process should be identified by __DATE__ and __TIME__. I would
think a conforming implementation could defer the evaluation of those
strings to build time (the compiler would have to supply place-holder text
and specify everyplace where that text appears within objects' initial
values, but designing that feature into a compiler and linker would not be
difficult).
Also, what happens if the computer/compiler isn't that fast, and the file
takes more than a second to preprocess? Can __TIME__ at the top of the file
be different than at the bottom of the file?

Finally, can the time be available at the top of the file, but not at the
bottom? (Consider, for example, a hardware clock that for some reason fails
during the compile. Or maybe your internet connection to nist.gov goes down.)

I would expect that any non-DS9K compiler would simply get the date/time at
the start of the compile, and keep using that throughout the compile. But
that doesn't mean the Standard requires it.

[...]
--
Kenneth Brody
Keith Thompson
2017-04-17 16:25:07 UTC
Reply
Permalink
Raw Message
Post by Ken Brody
Post by s***@casperkitty.com
Post by Keith Thompson
The problem would be that the expansions of __DATE__ and __TIME__ would
be whatever was passed on the compiler command line and not, as the
standard specifies and a reader will assume, the date and time of
translation.
The Standard does not require any particular degree of precision, nor does
it specify the means via which an implementation would determine the time.
There is no requirement that platforms which host C compilers need to have
any kind of real-time clock functionality. If a compiler included a
command-line option to say "Don't trust the system clock--the time is
actually 1989-06-05 04:32:10, I don't think the Standard would require that
the compiler not believe the command line.
NB: I am in no way a "language lawyer".
Looking at N1256 (yes, I know it's not the latest, but it's the latest I
"If the date of translation is not available, an implementation-defined
valid date shall be supplied."
A similar statement is made about __TIME__.
Without a detailed explanation of what "is not available" means, you could
easily say that "using compiler flag X will cause the compiler to behave as
if the date and time are not available" is still conforming.
IMHO, the requirement that the date "is not available" is not satisfied
by an option that tells the compiler to *pretend* the date is not
available.

I'd say that a compiler with that option specified is non-conforming,
simply because it violates the standard's reasonably clear requirements
for __DATE__ and __TIME__.

[...]
Post by Ken Brody
Also, what happens if the computer/compiler isn't that fast, and the file
takes more than a second to preprocess? Can __TIME__ at the top of the file
be different than at the bottom of the file?
The standard is less than crystal clear on this point, but I'd say that
a conforming implementation could have __TIME__ and __DATE__ have
different values within a source file.

For that matter, suppose a source file refers to __DATE__ and __TIME__
on the same line:
printf("%s %s\n", __DATE__, __TIME__);
It's possible that the expansion of __DATE__ could be determined just
before midnight, and the expansion of __TIME__ just after midnight (or
vice versa) resulting in a printed date and time that appear to be off
by 24 hours.
Post by Ken Brody
Finally, can the time be available at the top of the file, but not at the
bottom? (Consider, for example, a hardware clock that for some reason fails
during the compile. Or maybe your internet connection to nist.gov goes down.)
Possibly.
Post by Ken Brody
I would expect that any non-DS9K compiler would simply get the date/time at
the start of the compile, and keep using that throughout the compile. But
that doesn't mean the Standard requires it.
GNU cpp (used by gcc) appears to compute the expansion of __DATE__
and __TIME__ once per translation unit, when one of the macros is
encountered for the first time.

I just took a look at the GNU cpp manual. For __DATE__, it says:

If GCC cannot determine the current date, it will emit a warning
message (once per compilation) and '__DATE__' will expand to
'"??? ?? ????"'.

This contradicts the standard, which says:

If the date of translation is not available, an
implementation-defined valid date shall be supplied.

Likewise for __TIME__.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
James R. Kuyper
2017-04-17 16:45:26 UTC
Reply
Permalink
Raw Message
...
Post by Ken Brody
Post by s***@casperkitty.com
The Standard does not require any particular degree of precision, nor does
it specify the means via which an implementation would determine the time.
There is no requirement that platforms which host C compilers need to have
any kind of real-time clock functionality. If a compiler included a
command-line option to say "Don't trust the system clock--the time is
actually 1989-06-05 04:32:10, I don't think the Standard would require that
the compiler not believe the command line.
NB: I am in no way a "language lawyer".
Looking at N1256 (yes, I know it's not the latest, but it's the latest I
"If the date of translation is not available, an implementation-defined
valid date shall be supplied."
A similar statement is made about __TIME__.
Without a detailed explanation of what "is not available" means, you could
easily say that "using compiler flag X will cause the compiler to behave as
if the date and time are not available" is still conforming.
Yes, it would be trivial to support such a flag - but if the date and
time are in fact available, and the compiler is just pretending
otherwise, providing any other date and time value renders it
non-conforming, despite that pretense.

By analogy: if you and I have a formal written agreement that I will pay
you a specified amount of money to fix my windows, then if I pretend
that I can't see that your repairs are complete, and therefore refuse to
pay you, I'm still in violation of our agreement, despite that pretense.
Post by Ken Brody
Post by s***@casperkitty.com
Further, in the event that a project happens to be built in multiple steps
that occur days apart, I don't think the Standard specifies which moment in
the build process should be identified by __DATE__ and __TIME__.
The standard specifies that __DATE__ describes "The date of translation
of the preprocessing translation unit:" "The" is singular: only one
such data can apply in a given preprocessing translation unit. It's
entirely consistent with that wording for __DATE__ and __TIME__ to have
different values in different translation units translated at different
times, but it would be a very odd compiler that takes several days to
complete translation of a single preprocessing translation unit. Note,
in particular, that preprocessing translation units cease to exist by
the end of translation phase 4; linkage doesn't occur until translation
phase 8. Therefore, you can't justify waiting for the program to be
linked together before determining the appropriate value of __DATE__ or
__TIME__.
Post by Ken Brody
Post by s***@casperkitty.com
I would
think a conforming implementation could defer the evaluation of those
strings to build time (the compiler would have to supply place-holder text
and specify everyplace where that text appears within objects' initial
values, but designing that feature into a compiler and linker would not be
difficult).
Do you really know of any compiler so slow that translation of single
preprocessing translation unit takes several days to complete?
Post by Ken Brody
Also, what happens if the computer/compiler isn't that fast, and the file
takes more than a second to preprocess? Can __TIME__ at the top of the file
be different than at the bottom of the file?
The standard specifies that __TIME__ is "The time of translation of the
preprocessing translation unit:". Again, "The" is singular - only one
time can be associated with any given preprocessing translation unit. It
seems to me that the only way to assign a single time value to the
entire thing is to have that time associated with the beginning of
translation, since, in general, you can't be sure how long the
translation will take, and you generally need to have a specific value
for __DATE__ and __TIME__ by the end of translation phase 4 - without
those specific values, you can't be sure to do with code containing
those values during phases 5-8. It could be as early as the time when
the compiler first started up, or as late as the time the __TIME__ macro
was first translated - but I don't see any reasonable way for it to be
outside the range bounded by those two times.
Post by Ken Brody
Finally, can the time be available at the top of the file, but not at the
bottom? (Consider, for example, a hardware clock that for some reason fails
during the compile. Or maybe your internet connection to nist.gov goes down.)
If I'm right about it having to be a single time value, that issue
doesn't come up.
Keith Thompson
2017-04-17 19:02:32 UTC
Reply
Permalink
Raw Message
"James R. Kuyper" <***@verizon.net> writes:
[...]
[...]
Post by James R. Kuyper
Post by s***@casperkitty.com
Further, in the event that a project happens to be built in multiple steps
that occur days apart, I don't think the Standard specifies which moment in
the build process should be identified by __DATE__ and __TIME__.
The standard specifies that __DATE__ describes "The date of translation
of the preprocessing translation unit:" "The" is singular: only one
such data can apply in a given preprocessing translation unit. It's
entirely consistent with that wording for __DATE__ and __TIME__ to have
different values in different translation units translated at different
times, but it would be a very odd compiler that takes several days to
complete translation of a single preprocessing translation unit. Note,
in particular, that preprocessing translation units cease to exist by
the end of translation phase 4; linkage doesn't occur until translation
phase 8. Therefore, you can't justify waiting for the program to be
linked together before determining the appropriate value of __DATE__ or
__TIME__.
[...]

It wouldn't have to take several days for the problem to occur.

If translation phase 4 starts at 2017-04-17 23:59:59.99 and completes 20
milliseconds later at 2017-04-18 00:00:00.01, then the start and end
times would be on two different days. If __DATE__ and __TIME__ are
evaluated separately, you could end up with __DATE__ = "Apr 17 2017" and
__TIME__ = "00:00:00", implying a time 24 hours before the actual
translation time.

The use of the phrases "*The* date" and "*The* time" suggest, though
perhaps not strongly enough, that both __DATE__ and __TIME__ should
correspond to a single moment in time for each translation of each
translation unit. (A compiler might perform different phases at
different times, but only phase 4 is relevant here.)
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
James R. Kuyper
2017-04-17 19:23:25 UTC
Reply
Permalink
Raw Message
Post by Keith Thompson
[...]
[...]
Post by James R. Kuyper
Post by s***@casperkitty.com
Further, in the event that a project happens to be built in multiple steps
that occur days apart, I don't think the Standard specifies which moment in
the build process should be identified by __DATE__ and __TIME__.
The standard specifies that __DATE__ describes "The date of translation
of the preprocessing translation unit:" "The" is singular: only one
such data can apply in a given preprocessing translation unit. It's
entirely consistent with that wording for __DATE__ and __TIME__ to have
different values in different translation units translated at different
times, but it would be a very odd compiler that takes several days to
complete translation of a single preprocessing translation unit. Note,
in particular, that preprocessing translation units cease to exist by
the end of translation phase 4; linkage doesn't occur until translation
phase 8. Therefore, you can't justify waiting for the program to be
linked together before determining the appropriate value of __DATE__ or
__TIME__.
[...]
It wouldn't have to take several days for the problem to occur.
If translation phase 4 starts at 2017-04-17 23:59:59.99 and completes 20
milliseconds later at 2017-04-18 00:00:00.01, then the start and end
times would be on two different days. If __DATE__ and __TIME__ are
evaluated separately, you could end up with __DATE__ = "Apr 17 2017" and
__TIME__ = "00:00:00", implying a time 24 hours before the actual
translation time.
Agreed - I was responding to supercat's comment about "... a project
happens to be built in multiple steps that occur days apart ...", and
not to the problem itself. It's pretty clear he was thinking about
building of an entire program, for which that wording would be more
reasonable, rather than the translation of a single preprocessing
translation unit.
Post by Keith Thompson
The use of the phrases "*The* date" and "*The* time" suggest, though
perhaps not strongly enough, that both __DATE__ and __TIME__ should
correspond to a single moment in time for each translation of each
translation unit. (A compiler might perform different phases at
different times, but only phase 4 is relevant here.)
Exactly.
Lowell Gilbert
2017-04-18 17:27:03 UTC
Reply
Permalink
Raw Message
Post by Keith Thompson
The use of the phrases "*The* date" and "*The* time" suggest, though
perhaps not strongly enough, that both __DATE__ and __TIME__ should
correspond to a single moment in time for each translation of each
translation unit. (A compiler might perform different phases at
different times, but only phase 4 is relevant here.)
Not to mention that the first thing specified about "Predefined macro
names" is:
"The values of the predefined macros listed in the following
subclauses) (except for __FILE__ and __LINE__) remain constant
throughout the translation unit."
--
Lowell Gilbert, embedded/networking software engineer
http://be-well.ilk.org/~lowell/
Ken Brody
2017-04-18 18:23:24 UTC
Reply
Permalink
Raw Message
On 4/18/2017 1:27 PM, Lowell Gilbert wrote:
[...]
Post by Lowell Gilbert
Not to mention that the first thing specified about "Predefined macro
"The values of the predefined macros listed in the following
subclauses) (except for __FILE__ and __LINE__) remain constant
throughout the translation unit."
And there is our answer.

It's also in N1256, though worded differently -- 6.10.8.3:

The values of the predefined macros (except for __FILE__ and
__LINE__) remain constant throughout the translation unit.

Thanks.
--
Kenneth Brody
Keith Thompson
2017-04-18 19:10:44 UTC
Reply
Permalink
Raw Message
Post by Lowell Gilbert
Post by Keith Thompson
The use of the phrases "*The* date" and "*The* time" suggest, though
perhaps not strongly enough, that both __DATE__ and __TIME__ should
correspond to a single moment in time for each translation of each
translation unit. (A compiler might perform different phases at
different times, but only phase 4 is relevant here.)
Not to mention that the first thing specified about "Predefined macro
"The values of the predefined macros listed in the following
subclauses) (except for __FILE__ and __LINE__) remain constant
throughout the translation unit."
Well that settles it, then.

Note to self: Check the parent sections before posting. For example, if
you find something in section 6.10.8.1, also read the introductory
material in 6.10.8 and 6.10.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Richard Bos
2017-04-22 21:20:42 UTC
Reply
Permalink
Raw Message
Post by James R. Kuyper
Post by Ken Brody
Looking at N1256 (yes, I know it's not the latest, but it's the latest I
"If the date of translation is not available, an implementation-defined
valid date shall be supplied."
A similar statement is made about __TIME__.
Without a detailed explanation of what "is not available" means, you could
easily say that "using compiler flag X will cause the compiler to behave as
if the date and time are not available" is still conforming.
Yes, it would be trivial to support such a flag - but if the date and
time are in fact available, and the compiler is just pretending
otherwise, providing any other date and time value renders it
non-conforming, despite that pretense.
By analogy: if you and I have a formal written agreement that I will pay
you a specified amount of money to fix my windows, then if I pretend
that I can't see that your repairs are complete, and therefore refuse to
pay you, I'm still in violation of our agreement, despite that pretense.
On the other hand, if I have a Moroccan restaurant and one of my dishes
is a tajine with chicken, dates, tomatoes and ras el hanout; and you
order that tajine but say "hold the dates, please"; then I am not in
contravention of any Trading Standards Act if I serve it to you without.

Analogies, I'm afraid, make good illustrations but bad rules.

Richard
James Kuyper
2017-04-23 02:45:01 UTC
Reply
Permalink
Raw Message
Post by Richard Bos
Post by James R. Kuyper
Post by Ken Brody
Looking at N1256 (yes, I know it's not the latest, but it's the latest I
"If the date of translation is not available, an implementation-defined
valid date shall be supplied."
A similar statement is made about __TIME__.
Without a detailed explanation of what "is not available" means, you could
easily say that "using compiler flag X will cause the compiler to behave as
if the date and time are not available" is still conforming.
Yes, it would be trivial to support such a flag - but if the date and
time are in fact available, and the compiler is just pretending
otherwise, providing any other date and time value renders it
non-conforming, despite that pretense.
By analogy: if you and I have a formal written agreement that I will pay
you a specified amount of money to fix my windows, then if I pretend
that I can't see that your repairs are complete, and therefore refuse to
pay you, I'm still in violation of our agreement, despite that pretense.
On the other hand, if I have a Moroccan restaurant and one of my dishes
is a tajine with chicken, dates, tomatoes and ras el hanout; and you
order that tajine but say "hold the dates, please"; then I am not in
contravention of any Trading Standards Act if I serve it to you without.
Analogies, I'm afraid, make good illustrations but bad rules.
I don't see a problem with either analogy. Your analogy corresponds to
to a case where someone wants non-conforming behavior from a compiler,
non-conforming behavior that the compiler promises to provide if the
appropriate option is selected. It's perfectly true that they have no
legitimate grounds for complaint if they get that behavior when choosing
that option. But it's also still true that the behavior is
non-conforming. I was objecting to the claim that the implementation
could be considered "still conforming" - I wasn't saying anything about
whether or not the users would be happy to see it fail to conform in
that fashion - obviously they would be if their use of that option was
deliberate.

Tim Rentsch
2017-04-17 18:30:01 UTC
Reply
Permalink
Raw Message
[.. what if -D__DATE__=... or -D__DATE__=... is given? ..]
The problem would be that the expansions of __DATE__ and __TIME__ would
be whatever was passed on the compiler command line and not, as the
standard specifies and a reader will assume, the date and time of
translation.
On the other hand, compilers *are* allowed to do that (the option is
typically "-D" rather than "-d", and the quoting needs to be fixed if
that's supposed to be part of a shell command line). The standard
(6.10.8p2) says that none of the predefined macro names shall be the
subject of #define or #undef, but that's not a constraint, so it is at
most undefined behavior -- and the standard doesn't talk about -D.
[...]
Under the provisions of 7.1.3, any definition (ie, and not just #define)
of such names gives undefined behavior.

Also, the documentation for gcc says about -Dname=definition "[t]he
contents of definition are tokenized and processed as if they appeared
during translation phase three in a #define directive." That too
means undefined behavior.

The documentation for clang says that -Dmacroname=value "[a]dds an
implicit #define into the predefines buffer which is read before the
source file is preprocessed." Also undefined behavior.

Most likely using -D to give a value to __DATE__ or __TIME__ will
work fine and do what everyone expects. As far as the Standard
is concerned, it looks like it's just undefined behavior.
Keith Thompson
2017-04-17 19:30:05 UTC
Reply
Permalink
Raw Message
Post by Tim Rentsch
[.. what if -D__DATE__=... or -D__DATE__=... is given? ..]
The problem would be that the expansions of __DATE__ and __TIME__ would
be whatever was passed on the compiler command line and not, as the
standard specifies and a reader will assume, the date and time of
translation.
On the other hand, compilers *are* allowed to do that (the option is
typically "-D" rather than "-d", and the quoting needs to be fixed if
that's supposed to be part of a shell command line). The standard
(6.10.8p2) says that none of the predefined macro names shall be the
subject of #define or #undef, but that's not a constraint, so it is at
most undefined behavior -- and the standard doesn't talk about -D.
[...]
Under the provisions of 7.1.3, any definition (ie, and not just #define)
of such names gives undefined behavior.
That's questionable IMHO. It says the behavior is undefined if the
*program* declares, defines, or undefines a reserved identifier.
Arguably if I compile with `gcc -D__DATE__=...`, it's not the program
that's defining it. A minor quibble, and ...
Post by Tim Rentsch
Also, the documentation for gcc says about -Dname=definition "[t]he
contents of definition are tokenized and processed as if they appeared
during translation phase three in a #define directive." That too
means undefined behavior.
The documentation for clang says that -Dmacroname=value "[a]dds an
implicit #define into the predefines buffer which is read before the
source file is preprocessed." Also undefined behavior.
Most likely using -D to give a value to __DATE__ or __TIME__ will
work fine and do what everyone expects. As far as the Standard
is concerned, it looks like it's just undefined behavior.
Agreed.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Richard Bos
2017-04-22 21:24:45 UTC
Reply
Permalink
Raw Message
Post by Keith Thompson
Post by Tim Rentsch
Under the provisions of 7.1.3, any definition (ie, and not just #define)
of such names gives undefined behavior.
That's questionable IMHO. It says the behavior is undefined if the
*program* declares, defines, or undefines a reserved identifier.
Arguably if I compile with `gcc -D__DATE__=...`, it's not the program
that's defining it. A minor quibble, and ...
I don't think it's even a minor quibble, and I don't think it even needs
to be argued. It's quite clearly _not_ the program which defines those
constants, but the implementation. After all, if you compiled the same
source code with different options, you'd get a different result. That
the implementation gets the value of its implementation-defined
constants from the command line rather than from an options file or from
its own internal code, _that_ is a minor quibble; it is still perfectly
evident that it _is_ the implementation which defines them, and not the
source under translation.

Richard
Gordon Burditt
2017-04-14 18:35:05 UTC
Reply
Permalink
Raw Message
Warnings like -Wdate-time are intended for pedants who need to
exactly match source code to object code. If you aren't a pedant,
don't use it.

For those who insist that everyone must always turn on all warnings:
A warning like -Weverything should always produce a warning that
-Weverything is turned on, plus warnings about all unimplemented
warnings (hint: there are an infinite number of unimplemented
warnings). It should also warn about compilations done third shift
(e.g. 1AM - 9AM) and on holidays as coding done during these times
is more likely to have errors in it, and it should warn if compilation
is done on Friday the 13th (bad luck) or during a full moon
(werewolves).

Reproducing the exact binary from source can be important for testing
compilers. The triple-compile test is often done to bootstrap
compilers from an unknown version of an unknown compiler to get to
a known version of a known compiler. GCC builds from source use
this. It's also a pretty sensitive test for finding bugs when
working on code-generation or optimization in a compiler.

It can also be an issue for determining if the software has been
tampered with (e.g. viruses) after it has been certified, say, in
voting machine software or FAA-approved flight control software.
Comparing checksums of a known-good binary also works, but it may
not be enough when the source code is subpoenaed in court and proof
demanded that it is the real source code matching what Flight 666
was running when it crashed.

A "computer archeologist" may be tasked with retrieving long-lost
source code from company archives for some ancient binary still in
use so an important fix (say, y2k compliance, or, more relevant
today, January 19, 2038 compliance, when a signed 32-bit UNIX
timestamp overflows. This may not be much of a problem as a lot
of current UNIX-like software already uses 64-bit timestamps.) can
be made and it is important to determine whether the source code
matches the binary before investing too much effort in applying a
fix, otherwise you may lose long-forgotten but important changes.
Such code may not have reliable version tags, and in any case might
have been subject to binary patches later. The alternative may be
to reverse-engineer the binary, which can be expensive and
time-consuming.

There is a published instance where a compiler was tampered with,
to (1) insert a back door into the login program, and (2) insert
the tampering with the compiler code into the compilation from clean
source, so that re-building the entire UNIX system from un-tampered-with
source and the binaries of a tampered-with compiler would re-generate
the tampered-with compiler and login program. This was published
in the Bell Systems Technical Journal in 1984 by Ken Thompson. As
I recall, the title was something like "Reflections on Trusting
Trust". Matching source to object code isn't foolproof if the
compiler has been tampered with.



Putting the date or time of compilation into the object code (as
opposed to putting the date or time of modification of the source
code) can cause unimportant but annoying (if you need to check an
exact match) differences. I'd expect only those who have a need
for checking that the source reproduces the object exactly would
enable warnings like -Wdate-time.

Another possible issue is linkers which stick a time-of-link time
stamp into the executable. For systems where this cannot be disabled,
you need an object-comparison and executable-comparison tools that
compare every part of the files except the time stamp. It may also
be that you need tools that ignore differences in the format of or
presence of debugging symbols in the comparison.

A triple-compile test can be very valuable for finding compiler
bugs. You run one like this:

1. Compile the compiler source code with any old compiler you've
got around (such as the last-known-stable version of the compiler
you are developing, or the compiler your system came with).
Call the result C1.

2. Compile the same compiler source code with C1. Call the result
C2.

3. Compile the same compiler source code with C2. Call the result
C3.

If C2 and C3 are not identical except for trivial differences
(__DATE__, __TIME__ and __TIMESTAMP__ macros and linker time stamps
would be included here, as would differences in compiler options.
Library differences, if you're not recompiling the libraries each
time, are also expected. Don't do that when running a triple-compile
test), chances are high that there's a bug either in the compiler
being built, or perhaps the compiler you started with. C1 and C2
may legitimately be different as differences in code generation and
optimization are likely. However, they should generate the same
code when given the same source, so C2 and C3 should not have
differences.
s***@casperkitty.com
2017-04-14 19:17:42 UTC
Reply
Permalink
Raw Message
Post by Gordon Burditt
A triple-compile test can be very valuable for finding compiler
1. Compile the compiler source code with any old compiler you've
got around (such as the last-known-stable version of the compiler
you are developing, or the compiler your system came with).
Call the result C1.
2. Compile the same compiler source code with C1. Call the result
C2.
3. Compile the same compiler source code with C2. Call the result
C3.
How about taking any two compilers one has lying around, and compiling
the compiler source with each, then with the compilers produced thereby,
and then with the compilers produced by those. That would ensure that
any secret code-tampering logic which was present in either of the
originals couldn't undetectably alter the results unless the exact same
code-tampering logic was present in both originals.
Gordon Burditt
2017-04-16 05:04:44 UTC
Reply
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Gordon Burditt
A triple-compile test can be very valuable for finding compiler
1. Compile the compiler source code with any old compiler you've
got around (such as the last-known-stable version of the compiler
you are developing, or the compiler your system came with).
Call the result C1.
2. Compile the same compiler source code with C1. Call the result
C2.
3. Compile the same compiler source code with C2. Call the result
C3.
How about taking any two compilers one has lying around, and compiling
the compiler source with each, then with the compilers produced thereby,
and then with the compilers produced by those.
You forgot to explicitly state the step where you compare the final
executables for each set of compilations against each other. It's
important, even though I know that's what was meant.
Post by s***@casperkitty.com
That would ensure that
any secret code-tampering logic which was present in either of the
originals couldn't undetectably alter the results unless the exact same
code-tampering logic was present in both originals.
That's fine as far as it goes. It doesn't handle a number of other
possible problems for the paranoid:

- If you pick two versions of GCC (or two versions from any other
vendor), there's a high probability that if one was tampered with
at the vendor, the tampering is also present in a later version.

- If you pick two very different compilers, they don't run on the
same platform or generate code for the same CPU and the same OS,
making the executables nothing alike.

- The OS has been tampered with to make the compiler act differently.

- The hypervisor has been tampered with to make the compiler act
differently.

- The CPU has been tampered with to make the compiler act differently.
Do you really think Intel and AMD and other CPU manufacturers
haven't been compromised by the NSA?

- The tampering is in the C library, not the compiler proper, and
all compilers for the platform use the same C library (msvcrt.dll,
anyone?) Nobody ever recompiles it because they don't have the
source code (I presume: Microsoft rarely makes source code
available, and I'm guessing msvcrt.dll is no exception.)

Also, the triple-compile test is really much more useful for
discovering accidental bugs, not intentional tampering where the
tamperer may try to interfere with any tests you might run, or
conveniently kill you with an explosion in your cell phone battery
before the test results are in.

I do recall a similar problem of hidden data transfer from a tool
to its output that really happened: long, long ago. The tool was
a z80 assembler running on a TRS-80 Model II. Building it usually
used a previously known-good version of that same assembler.

1. At one point, the feature was added to permit using the name
of an opcode as a symbol that had as its value the value of the
machine opcode. The opcode table had fields like opcode name,
machine opcode value, what type of arguments it took (registers,
1-byte immediate data, 2-byte immediate data, address, etc.)
and the address of a handler that processed that opcode.

2. At a later point, the assembler was changed to use feature #1
in its opcode table.

Much later, someone complains that the opcode value generated by
one of the more obscure z80 opcodes was wrong. (OTIR, I think.) I
look at the output of the sample code given, then reproduce it. I
then look at the manuals for the z80 processor. Yep, it's wrong.
Further, the assembler produced the same opcode value for two
different opcode names, so it was unlikely to be a typo introduced
into the manufacturer documentation after the assembler was written.
So I then go to the source code. There's no place in the source
code where the value of that opcode appears!

Ever since change #2, the values of the opcodes were passed down
from predecessor to the current version. Patching the binary, then
rebuilding from unchanged source using the fixed assembler (which
would re-create the binary with the patch already in it!) would fix
it.

I think the real fix was to revert change #2 above. This was done
very carefully, as there were many unrelated changes done since
then:

1. replace in the opcode table the symbol with the value
of the opcode, except DO NOT fix the incorrect opcode
(which the assembler didn't use in its own code). This
is a big change where typographical errors are likely
and would be a disaster. Also add a detailed comment
of why not to re-apply change #2 no matter how good an
idea it may seem to be.

2. Re-assemble and verify that the executable didn't change.

3. Now fix the incorrect opcode. There's a place in the
source code to change it now.

4. Re-assemble. Verify that only one byte changed. Verify
that the sample source code assembles correctly. Just for
thoroughness, assemble the test file that includes all
opcodes and make sure nothing else changed.

5. Update the master source archive with the new version
and inform everyone who might have a private copy to
update it. (No source code control systems then on
desktop floppy-disk computers, and I don't think the
Model II even had a hard disk (8 megabytes. no, not
RAM or cache, hard disk space.) yet.)

The only way you would have detected this with using two different
assemblers to build the one of interest would be if one of the
assemblers you picked had the value of an opcode wrong. Also, as
features were added, probably the only assembler that could assemble
the source code of interest was the assembler of interest anyway.
Z80 assemblers weren't nearly as standardized as C.
Noob
2017-04-16 09:04:39 UTC
Reply
Permalink
Raw Message
Post by s***@casperkitty.com
How about taking any two compilers one has lying around, and compiling
the compiler source with each, then with the compilers produced thereby,
and then with the compilers produced by those. That would ensure that
any secret code-tampering logic which was present in either of the
originals couldn't undetectably alter the results unless the exact same
code-tampering logic was present in both originals.
Reflections on Trusting Trust
https://dl.acm.org/citation.cfm?id=1283940&CFID=751525768&CFTOKEN=11767401

Countering "Trusting Trust" through Diverse Double-Compiling
http://www.acsa-admin.org/countering-trusting-trust-through-diverse-double-compiling/
s***@casperkitty.com
2017-04-16 18:52:34 UTC
Reply
Permalink
Raw Message
Post by Noob
Post by s***@casperkitty.com
How about taking any two compilers one has lying around, and compiling
the compiler source with each, then with the compilers produced thereby,
and then with the compilers produced by those. That would ensure that
any secret code-tampering logic which was present in either of the
originals couldn't undetectably alter the results unless the exact same
code-tampering logic was present in both originals.
Reflections on Trusting Trust
https://dl.acm.org/citation.cfm?id=1283940&CFID=751525768&CFTOKEN=11767401
Countering "Trusting Trust" through Diverse Double-Compiling
http://www.acsa-admin.org/countering-trusting-trust-through-diverse-double-compiling/
I hadn't thought about the problems of floating-point constants mentioned
in the latter paper, though those could be mitigated if one chose a compiler
which performed all of its internal math using integer types no longer than
32 bits (so as to allow bootstrapping via systems and compilers that are as
old as practical) and was designed to make the output be dependent solely
upon the source and configuration options. If one of the first-stage
implementations is a lightweight 1990s compiler running on a 1990s computer,
it would be exceptionally unlikely that it could hide anything malicious
because there would be no "room" for such a thing.
Richard Bos
2017-04-22 21:28:53 UTC
Reply
Permalink
Raw Message
Post by Noob
Post by s***@casperkitty.com
How about taking any two compilers one has lying around, and compiling
the compiler source with each, then with the compilers produced thereby,
and then with the compilers produced by those. That would ensure that
any secret code-tampering logic which was present in either of the
originals couldn't undetectably alter the results unless the exact same
code-tampering logic was present in both originals.
Reflections on Trusting Trust
https://dl.acm.org/citation.cfm?id=1283940&CFID=751525768&CFTOKEN=11767401
Countering "Trusting Trust" through Diverse Double-Compiling
http://www.acsa-admin.org/countering-trusting-trust-through-diverse-double-compiling/
Double compiling... amateurs.

_Cross_-compile, then compile an interpreter for another language, in
that interpreter run a compiler for your own in-house language, in that
write a new compiler for the original language, and only then
cross-compile back.
Good luck getting a back door through GCC on Linux, Inform, Nu-Bazic,
TinyC on MacOS 9, back to GCC.

Richard
Joe Pfeiffer
2017-04-19 03:34:05 UTC
Reply
Permalink
Raw Message
Post by Kenny McCormack
...
Post by MehdiAmini
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"DATE:%s\n",__DATE__);
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"TIME:%s\n",__TIME__);
What to do to fix the warnings?
Barry has given you the answer - if you don't want these warnings, then do
whatever's necessary to inhibit the warnings.
But I think what you're really asking is "What does this warning mean?"
-Wdate-time
Warn when macros "__TIME__", "__DATE__" or "__TIMESTAMP__" are
encountered as they might prevent bit-wise-identical reproducible
compilations.
which seems pretty pedantic to me. I doubt anyone really cares about this.
There are certainly people who do care -- see

https://wiki.debian.org/ReproducibleBuilds

to learn more.
Post by Kenny McCormack
And, to expand on that comment, I've generally found that compilation is
not entirely deterministic - which is to say that I've never relied upon,
nor have I ever assumed, nor have I ever expected to be able to assume or
to rely upon the results of one compilation to be bitwise identical to the
results of any other compilation (even though all inputs and conditions are
otherwise identical).
So, it all seems kind of hinky to me.
Keith Thompson
2017-04-17 15:09:04 UTC
Reply
Permalink
Raw Message
MehdiAmini <***@gmail.com> writes:
[...]
Post by MehdiAmini
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"DATE:%s\n",__DATE__);
^
warning: expansion of date or time macro is not reproducible [-Wdate-time]
fprintf(stderr,"TIME:%s\n",__TIME__);
What to do to fix the warnings?
Can you explain clearly why you're using the -Wdate-time option in the
first place?
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Loading...