Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 2 Dec 2014 17:47:54 -0500
From: Rich Felker <dalias@...c.org>
To: Jens Gustedt <jens.gustedt@...ia.fr>
Cc: musl@...ts.openwall.com
Subject: Re: [PATCH 1/4] the CMPLX macros must be usable in
 initializations of static variables

On Tue, Dec 02, 2014 at 11:00:12PM +0100, Jens Gustedt wrote:
> Am Dienstag, den 02.12.2014, 14:42 -0500 schrieb Rich Felker:
> > On Tue, Dec 02, 2014 at 08:10:32PM +0100, Jens Gustedt wrote:
> > > > Does clang not support the GCC builtin?
> > > 
> > > no, and I don't have the impression they will. They invented their own
> > > internals for this, as you can see here.
> > 
> > Yes, but their form is a bug that needs to be removed, so they'll have
> > to add something in its place, and __builtin_complex is the natural
> > choice. For what it's worth, glibc only supports __builtin_complex and
> > just does not define these macros at all if it's not supported.
> 
> you mean it is a bug because the two-value-initializer is a constraint
> violation? It only is a bug that has to be diagnosed if user code is
> using it. Internals as long they are not visible to the user isn't
> covered by this, I think. And this is exactly the reason why the
> macros have been introduced in C11, to hide such cruft from the user's
> eye :)

Well, maybe, if they handle it via warning suppression in the system
header path. But this seems fragile.

> > > > My preference would be if we could just define CMPLX either in terms
> > > > of __builtin_complex,
> > > 
> > > not possible, I think
> > 
> > Well, it's what glibc does. That's not to say it's a good choice, but
> > it suggests there could be pressure to get other compilers to support
> > it.
> 
> and that's then one of the points where they aren't C11 conforming
> when compiled with other compilers

Then what about something like

#if __clang__ // && __clang_major__*100+__clang_minor__ <= xxxxx
// use clang compound literal hack
#elif __GNUC__*100+__GNUC_MINOR__ >= 407
// use __builtin_complex
#else
// use _Complex_I with mult and add
#endif

or alternatively:

#if __clang__ // && __clang_major__*100+__clang_minor__ <= xxxxx
// use clang compound literal hack
#else
// use __builtin_complex
#endif

I somewhat prefer the latter since the _Complex_I form is never really
correct (INF/NAN issues) and it gives better fallback behavior
assuming other compilers will implement __builtin_complex but might
not identify themselves as "GNU C >= 4.7". It also produces an error
on compilers that can't give the right behavior for INF/NAN rather
than silently miscompiling the code.

> > > > _Imaginary_I
> > > > is not supported yet at all and would require further changes to this
> > > > header to add anyway (this header is responsible for defining it), so
> > > > conditioning on its definition is not meaningful.
> > > 
> > > I am not sure of that. It could also come directly from the compiler
> > > just as it defines some __SOMETHING__ macros before any include
> > 
> > I don't think so. Consider:
> > 
> > #undef _Imaginary_I
> > #include <complex.h>
> > 
> > Perhaps this is non-conforming for technical reasons,
> 
> it is non-conforming

Because of the _-prefixed namespace? Per my understanding, it's
conforming to #undef macros provided by the standard headers in many
cases. Eliminating a function-like macro to get at the underlying
function is one such usage mentioned in the standard, but I think
there are others too.

> > but the standard
> > is fairly direct in saying that complex.h defines the _Imaginary_I
> > macro rather than just having it predefined.
> 
> but it also says
> 
>  » Implementations that define the macro __STDC_NO_COMPLEX__ need not provide
>  » this header nor support any of its facilities.
> 
> so any of the facilities *may* be provided anyhow. (and since
> _Imaginary_I is reserved it is allowed to do that in any case.)
> 
> But if you want to avoid that branch, I understand. _Imaginary_I would
> be *the* way to solve all of this easily, sigh.

Yes, I really wish GCC would support it, especially since Annex G
_requires_ _Imaginary_I, and glibc falsely advertises Annex G support
via the __STDC_IEC_559_COMPLEX__ macro despite not having
_Imaginary_I. But the glibc folks seem to think this is a non-issue
and I haven't seen any interest in fixing it on the GCC side.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.