This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/51013] complex::{imag,real}() should maintain lvalue-returning extension in C++11
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sun, 06 Sep 2015 18:45:02 +0000
- Subject: [Bug libstdc++/51013] complex::{imag,real}() should maintain lvalue-returning extension in C++11
- Auto-submitted: auto-generated
- References: <bug-51013-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51013
--- Comment #15 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Ross Martin from comment #14)
> This change to not be able to pull out a reference to the real or imaginary
> parts has messed me up. The assumption being made by this new complex class
> is that the real and imaginary parts are just a float or a double.
No, because if they are float or double then the corresponding explicit
specialization would be used. If the primary template is used then the type
must be some other type.
> That is
> false in my code, and doesn't seem to be a good assumption for a
> general-purpose complex implementation.
It's what the C++ standard specifies.
> My code has real and imaginary
> parts that are themselves full classes. These classes can, at times, act
> like double-precision numbers, so it makes sense to build complex numbers
> out of them for arithmetic manipulations. However, I need direct access to
> the real and imaginary parts to be able to access other parts of the class
> parameters, and this new complex-class implementation explicitly forbids any
> direct access to the real and imaginary parts in a type-safe way that
> doesn't rely on knowledge of internal class data organization. Not a good
> change, IMHO.
Did you read http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#387 ?
Have you looked at [complex.numbers] in the C++ standard? It says exactly how
to do it:
If z is an lvalue expression of type cv std::complex<T> then
the expression reinterpret_cast<cv T(&)[2]>(z) is well-formed; and
reinterpret_cast<cv T(&)[2]>(z)[0] designates the real part of z; and
reinterpret_cast<cv T(&)[2]>(z)[1] designates the imaginary part of z.
Moreover, if a is an expression of pointer type cv complex<T>* and the
expression a[i] is well-defined for an integer expression i then:
reinterpret_cast<cv T*>(a)[2*i] designates the real part of a[i]; and
reinterpret_cast<cv T*>(a)[2*i+1] designates the imaginary part of a[i].
Rather than forbidding direct access to the real and imaginary parts the
standard explicitly requires this to work, so your concern about relying on
internal class data organization is unfounded. You can rely on it because the
standard says so.