On 10/02/2017 11:07 AM, Jakub Jelinek wrote:
On Mon, Oct 02, 2017 at 10:41:59AM -0600, Martin Sebor wrote:
I also take back what I said about application programs being
unaffected by this.  Using the declaration to make these decisions
results in less optimal code when compiling in strict conformance
mode (e.g., -std=c11 or -std=c++14) than in "relaxed mode" (-std=
gnu11 or -std=gnu++14).  This can be seen using the following test
case:

Only for C, and even for -std=c99 or -std=c11 one can use -D_GNU_SOURCE
or -D_POSIX_C_SOURCE=200809 or -D_XOPEN_SOURCE=700 and various others
to make stpcpy available.  For C++ we define _GNU_SOURCE (unfortunately)
unconditionally.

That's not what I see.  Making the stpcpy declaration available
doesn't enable the transformation in strict mode.  What's more,
in strict mode GCC transforms stpcpy calls to strcpy.


  #include <string.h>

  void f (char *d, const char *s)
  {
    strcpy (d, s);

    if (__builtin_strlen (d) != __builtin_strlen (s))
       __builtin_abort ();
  }

I understand this is because, as you said, in strict mode, stpcpy
could be declared to be a different symbol.  After our discussion
I will (hopefully) remember this and avoid getting surprised by
it in the future.  But it still feels like a subtlety that should
be more prominently advertised somehow/somewhere to help others
avoid falling into the same trap.

Why should it be advertised?  It is an optimization.  We use it when
we feel it is safe to do so.  It isn't something that should be documented
in user manuals IMNSHO.

By "others" I was referring to other GCC developers.  I also
had in mind something a little less subjective than "do it when
you feel it's safe."  Clearly, in the case of strcpy to stpcpy,
the decision doesn't depend on how we feel but on what a valid
program in a given conformance mode can do.

But I think it would be helpful even to users to document the
rules for when a call to a standard library function can be
expected to be emitted (or optimized inline) and when it can
be expected to be transformed to another.

In the case of strcpy, GCC not only transforms it to stpcpy but
it also does the opposite transformation.  I.e., in strict mode
it transforms even calls to __builtin_stpcpy to strcpy.  That
would make sense to me because of what we said about defining
one's own non-standard stpcpy.  But GCC doesn't do that for
calls to other such ("semi-standard") built-in functions.  For
example, for a call to __builtin_strdup GCC emits a call to
strdup regardless of the language conformance mode.  Ditto for
__builtin_index.  The inconsistency raises questions about what
is actually intended.

IMO, a reasonable question a GCC user might ask is: when I make
a call to a standard library function via __builtin_foo() in
a language conformance mode where foo is not a standard function,
can I expect GCC to transform it to some equivalent call to
a function that is defined by the standard (or expand it inline)?
I don't know what the answer should be, but whatever we might
want it to be, it seems worth documenting.

Martin

Reply via email to