This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: GCC's statement expression extension


>>>>> "Mike" == Mike Stump <mrs@windriver.com> writes:

    Mike> I find the argument where a person misuses #defines and
    Mike> doesn't meet the requirements of the standard and breaks
    Mike> conformant code this way, while implementing parts of the
    Mike> standard, to be not very convincing.  They can misuse a good
    Mike> number of features to break user code already.

I seem to be getting into an awful lot of heated philosophical
arguments lately.  How unpleasant.

The bottom line is that if statement-expressions do not appear in
glibc macros, out problems will be largely solved -- independent of
questions about the semantics of statement expressions, or the
correctness of the implementation.  They may or may not actually work
in C++ -- but they will work about as well as they ever did before,
and people who write conforming code will see conforming behavior.
Furthermore, I bet no one will complain about bugs in the
statement-expression code, since I think very few people use it in
C++.  So, I will be happy to have it live on, if that's what people
want.

The problems with glibc headers were what motivated my original
statement-expression investigation some months ago, so let's stay
focused on that.

It sounds like we are all agreed that under any proposed semantics
for statement-expressions, code like:

  #define foo(X) ({ int i = X; i + 1; })

should not appear in glibc headers (at least when compiling C++) since
it is not conforming in C++, since it will result in early destruction
of temporaries for C++ objects that occur during the creation of X.
(I think one of Alexandre's proposals would not have had this problem,
but I think the rest of us weren't too happy with those semantics,
which involved not destroying any temporaries created in the
statement-expression until much later.)

I believe that this use of statement-expressions is the primary
motivation for their use in glibc headers -- you want to avoid
evaluating something more than once, so you store it in a local
variable, declared in a statement-expression.  

Since this does not work correctly in C++, can we agree that this
usage should be removed from glibc when compiling C++?  Also, can we
add a note to the documentation section on statement-expressions in
C++ giving this example, and explaining how it can surprise C++ users,
so that people who go read about this extension in C will at least be
aware that there are issues with this extension in C++?

By the way, on my system, I tried to find uses of this stuff in the
standard headers, and this is what I came up with under /usr/include:

  bash$ find . -name '*.h' | xargs -n10 grep -l '({'
  ./glib.h
  ./bits/byteswap.h
  ./bits/mathinline.h
  ./bits/select.h
  ./bits/sigset.h
  ./bits/stdio.h
  ./bits/string2.h
  ./bits/waitstatus.h
  ./ctype.h
  ./libintl.h
  ./math.h
  ./obstack.h
  ./string.h
  ./sys/wait.h
  ./tgmath.h
  ./unistd.h
  ./applet-widget.h

Although are a few instances of the pseudo-template stuff that we
talked about in tgmath.h, most of these are simple optimizations.  If
nothing else, we can fall back to the out-of-line versions of things,
which will be at least correct.  In most cases, we could also use an
inline-version of things.  Since C++ uses tree-based inlining, and
since the tree-based inliner tries to just substitute constants into
inlined functions, it is even likely that builtin_constant_p will
work for C++ on inlined functions.  

Indeed:

  inline int f (const char *const s)
  {
    if (__builtin_constant_p (s))
      return 1;
    else 
      return 0;
  }

  int g ()
  {
    return f ("abc");
  }

compiles to:

  g__Fv:
  .LFB1:
	  pushl	%ebp
  .LCFI0:
	  movl	$1, %eax
	  movl	%esp, %ebp
  .LCFI1:
	  popl	%ebp
	  ret

in C++.  (In C, `g' will return 0, but since our function-at-a-time
work for C is nearly complete, that can be expected to change at some
point.)

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]