This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: GCC's statement expression extension
- To: mrs at windriver dot com
- Subject: Re: GCC's statement expression extension
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Tue, 01 Aug 2000 21:52:07 -0700
- Cc: per at bothner dot com, gcc at gcc dot gnu dot org
- Organization: CodeSourcery, LLC
- References: <200008020114.SAA09384@kankakee.wrs.com>
>>>>> "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