public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference
@ 2011-10-19  1:04 trashyankes at wp dot pl
  2011-10-19  1:35 ` [Bug c++/50785] " paolo.carlini at oracle dot com
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: trashyankes at wp dot pl @ 2011-10-19  1:04 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

             Bug #: 50785
           Summary: [C++0x][constexpr] static constexpr double undefined
                    reference
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: trashyankes@wp.pl
             Build: MinGW 4.6.0 20110210; MinGW 4.7.0 20110815


#include <complex>
using namespace std;

struct test
{
    static constexpr double value = 0.0003;
};
int main()
{
    complex<double> x = complex<double>(0,1)*test::value; 
    // D:\Praca\Trash/newmain.cpp:10: undefined reference to `test::value'
}

modyfing line 10 to
complex<double> x = complex<double>(0,1)*(1*test::value);
fix it.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x][constexpr] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
@ 2011-10-19  1:35 ` paolo.carlini at oracle dot com
  2011-10-19  8:35 ` redi at gcc dot gnu.org
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: paolo.carlini at oracle dot com @ 2011-10-19  1:35 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #1 from Paolo Carlini <paolo.carlini at oracle dot com> 2011-10-19 01:34:50 UTC ---
What happens if you add a definition: constexpr double test::value; after your
struct like you would for any non-constrexpr static data member?


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x][constexpr] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
  2011-10-19  1:35 ` [Bug c++/50785] " paolo.carlini at oracle dot com
@ 2011-10-19  8:35 ` redi at gcc dot gnu.org
  2011-10-19 12:34 ` paolo.carlini at oracle dot com
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2011-10-19  8:35 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-10-19 08:34:45 UTC ---
The definition is required, see [class.static.data] p3

"A static data member of literal type can be declared in the class definition
with the constexpr specifier; [...] The member shall still be defined in a
namespace scope if it is odr-used (3.2) in the program and the namespace scope
definition shall not contain an initializer."


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x][constexpr] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
  2011-10-19  1:35 ` [Bug c++/50785] " paolo.carlini at oracle dot com
  2011-10-19  8:35 ` redi at gcc dot gnu.org
@ 2011-10-19 12:34 ` paolo.carlini at oracle dot com
  2011-10-19 12:45 ` redi at gcc dot gnu.org
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: paolo.carlini at oracle dot com @ 2011-10-19 12:34 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #3 from Paolo Carlini <paolo.carlini at oracle dot com> 2011-10-19 12:34:23 UTC ---
Let's double check with Jason, the last line of the Description is a bit
upsetting. Seems also related to PR50087 / note that -O "fixes" it.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x][constexpr] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (2 preceding siblings ...)
  2011-10-19 12:34 ` paolo.carlini at oracle dot com
@ 2011-10-19 12:45 ` redi at gcc dot gnu.org
  2011-10-19 12:46 ` redi at gcc dot gnu.org
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2011-10-19 12:45 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-10-19 12:43:59 UTC ---
test::value is an lvalue, binding a reference to it is an odr-use

(1*test::value) produces an rvalue, the reference is not bound to test::value,
so it is not odr-used


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x][constexpr] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (3 preceding siblings ...)
  2011-10-19 12:45 ` redi at gcc dot gnu.org
@ 2011-10-19 12:46 ` redi at gcc dot gnu.org
  2011-10-19 12:49 ` paolo.carlini at oracle dot com
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2011-10-19 12:46 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-10-19 12:46:00 UTC ---
and I assume -O eliminates the reference binding due to inlining and value
propagation

this all seems normal for a missing definition of a static const member, like
dozens of other invalid PRs


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x][constexpr] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (4 preceding siblings ...)
  2011-10-19 12:46 ` redi at gcc dot gnu.org
@ 2011-10-19 12:49 ` paolo.carlini at oracle dot com
  2011-10-19 12:55 ` [Bug c++/50785] [C++0x] " daniel.kruegler at googlemail dot com
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: paolo.carlini at oracle dot com @ 2011-10-19 12:49 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #6 from Paolo Carlini <paolo.carlini at oracle dot com> 2011-10-19 12:47:47 UTC ---
I agree, I agree.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (5 preceding siblings ...)
  2011-10-19 12:49 ` paolo.carlini at oracle dot com
@ 2011-10-19 12:55 ` daniel.kruegler at googlemail dot com
  2011-10-19 12:58 ` [Bug c++/50785] [C++0x][constexpr] " paolo.carlini at oracle dot com
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-10-19 12:55 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #8 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-10-19 12:54:24 UTC ---
I agree that the test case should require the definition of the static member,
the actual reason being that the constraint in 3.2 p2,

"[..] unless it is an object that satisfies the requirements for appearing in a
constant expression [..]"

is not satisfied, because the operator* of complex is not constexpr. Changing
the reference to std::complex by

template<class T>
struct complex {
private:
    T data[2];
public:
    constexpr complex(T r = 0, T i = 0) : data{r, i} {}
    constexpr T real() { return data[0]; }
    constexpr T imag() { return data[1]; }
};

template<class T>
constexpr complex<T> operator*(const complex<T>& lhs, const T& rhs)
{
    return complex<T>(lhs.real() * rhs, lhs.imag() * rhs);
}

also fixes the initial problem, because now the expression

complex<double>(0,1)*test::value

satisfies the criteria to appear in a constant expression.

But I think that the replacement code

complex<double> x = complex<double>(0,1)*(1*test::value);

should also require the definition of test::value. It could be, that the
compiler now reduces the scope of the analysis to the sub-expression
(1*test::value). If so, this is either a compiler defect or a core language
defect, I'm not sure. It is arguable that the description

"[..] unless it is an object that satisfies the requirements for appearing in a
constant expression [..]"

is somewhat misleading, because it focuses on the object and not on the
expression where it is part of. This could be related to CWG #712 in this case.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x][constexpr] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (6 preceding siblings ...)
  2011-10-19 12:55 ` [Bug c++/50785] [C++0x] " daniel.kruegler at googlemail dot com
@ 2011-10-19 12:58 ` paolo.carlini at oracle dot com
  2011-10-19 13:04 ` [Bug c++/50785] [C++0x] " redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: paolo.carlini at oracle dot com @ 2011-10-19 12:58 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID

--- Comment #7 from Paolo Carlini <paolo.carlini at oracle dot com> 2011-10-19 12:50:34 UTC ---
I think the important message to vehicle to the users - correct me if I'm wrong
- is that constexpr isn't "miraculous" from this point of view, old-style
static and C++11 static constexpr data members both generally require out of
class definitions.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (7 preceding siblings ...)
  2011-10-19 12:58 ` [Bug c++/50785] [C++0x][constexpr] " paolo.carlini at oracle dot com
@ 2011-10-19 13:04 ` redi at gcc dot gnu.org
  2011-10-19 13:09 ` daniel.kruegler at googlemail dot com
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2011-10-19 13:04 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-10-19 13:04:29 UTC ---
(In reply to comment #8)
> I agree that the test case should require the definition of the static member,
> the actual reason being that the constraint in 3.2 p2,
> 
> "[..] unless it is an object that satisfies the requirements for appearing in a
> constant expression [..]"

The rest of the sentence is relevant:
"... and the lvalue-to-rvalue conversion (4.1) is immediately applied."

> is not satisfied, because the operator* of complex is not constexpr.

I disagree.  It is odr-used because the lvalue-to-rvalue conversions is not
immediately applied.

In (1*test::value) the lvalue-to-rvalue conversion is immediately applied.

> Changing
> the reference to std::complex by
> 
> template<class T>
> struct complex {
> private:
>     T data[2];
> public:
>     constexpr complex(T r = 0, T i = 0) : data{r, i} {}
>     constexpr T real() { return data[0]; }
>     constexpr T imag() { return data[1]; }
> };
> 
> template<class T>
> constexpr complex<T> operator*(const complex<T>& lhs, const T& rhs)
> {
>     return complex<T>(lhs.real() * rhs, lhs.imag() * rhs);
> }
> 
> also fixes the initial problem, because now the expression
> 
> complex<double>(0,1)*test::value
> 
> satisfies the criteria to appear in a constant expression.

It is the _object_ (i.e. test:value) that needs to satisfy the criteria for
appearing in a constant expression, not the expression containing it.

test::value satisfies the criteria.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (8 preceding siblings ...)
  2011-10-19 13:04 ` [Bug c++/50785] [C++0x] " redi at gcc dot gnu.org
@ 2011-10-19 13:09 ` daniel.kruegler at googlemail dot com
  2011-10-19 16:35 ` trashyankes at wp dot pl
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-10-19 13:09 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #10 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-10-19 13:07:44 UTC ---
(In reply to comment #9)
> I disagree.  It is odr-used because the lvalue-to-rvalue conversions is not
> immediately applied.
> 
> In (1*test::value) the lvalue-to-rvalue conversion is immediately applied.

I tend to agree. My first impression was that the core language is unclear
here, but after some rethought I think the core language is clear and your
argumentation chain is convincing to me.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (9 preceding siblings ...)
  2011-10-19 13:09 ` daniel.kruegler at googlemail dot com
@ 2011-10-19 16:35 ` trashyankes at wp dot pl
  2011-10-19 16:58 ` redi at gcc dot gnu.org
  2011-10-19 17:12 ` redi at gcc dot gnu.org
  12 siblings, 0 replies; 14+ messages in thread
From: trashyankes at wp dot pl @ 2011-10-19 16:35 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #11 from trashyankes at wp dot pl 2011-10-19 16:35:06 UTC ---
it will be possible to add better waring/error in this case?
is complicity misleading when you use `static const` or `static constexpr` for
long time and when you try get ref that value you get error.
its get very weird when you have two lines that use it and only one give error.
code:

struct test
{
    static const int z = 6;
    static constexpr double t = 0.001;
};
template<class T>
T ref(const T& i)
{
    return i;
}
template<class T>
T value(const T i)
{
    return i;
}

int main()
{
    value(test::z);
    value(test::t);
    ref(test::z); //error
    ref(test::t); //error
}

until today i thought this code is correct.
maybe some info when you try take ref from const static objects?


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (10 preceding siblings ...)
  2011-10-19 16:35 ` trashyankes at wp dot pl
@ 2011-10-19 16:58 ` redi at gcc dot gnu.org
  2011-10-19 17:12 ` redi at gcc dot gnu.org
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2011-10-19 16:58 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-10-19 16:58:05 UTC ---
(In reply to comment #11)
> it will be possible to add better waring/error in this case?

Not easily, the error you get is from the linker.  This has been discussed MANY
times in other bugzilla reports, search for PRs with status=RESOLVED and the
words "static const undefined reference"

> maybe some info when you try take ref from const static objects?

No, because there is nothing wrong with doing that as long as you have a
definition for the member.  I do not want the compiler to complain when I write
correct code just to remind people who write incorrect code not to forget
something.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c++/50785] [C++0x] static constexpr double undefined reference
  2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
                   ` (11 preceding siblings ...)
  2011-10-19 16:58 ` redi at gcc dot gnu.org
@ 2011-10-19 17:12 ` redi at gcc dot gnu.org
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2011-10-19 17:12 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785

--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-10-19 17:12:11 UTC ---
N.B. we wrote a FAQ entry about this:
http://gcc.gnu.org/wiki/VerboseDiagnostics#missing_static_const_definition


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2011-10-19 17:12 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-19  1:04 [Bug c++/50785] New: [C++0x][constexpr] static constexpr double undefined reference trashyankes at wp dot pl
2011-10-19  1:35 ` [Bug c++/50785] " paolo.carlini at oracle dot com
2011-10-19  8:35 ` redi at gcc dot gnu.org
2011-10-19 12:34 ` paolo.carlini at oracle dot com
2011-10-19 12:45 ` redi at gcc dot gnu.org
2011-10-19 12:46 ` redi at gcc dot gnu.org
2011-10-19 12:49 ` paolo.carlini at oracle dot com
2011-10-19 12:55 ` [Bug c++/50785] [C++0x] " daniel.kruegler at googlemail dot com
2011-10-19 12:58 ` [Bug c++/50785] [C++0x][constexpr] " paolo.carlini at oracle dot com
2011-10-19 13:04 ` [Bug c++/50785] [C++0x] " redi at gcc dot gnu.org
2011-10-19 13:09 ` daniel.kruegler at googlemail dot com
2011-10-19 16:35 ` trashyankes at wp dot pl
2011-10-19 16:58 ` redi at gcc dot gnu.org
2011-10-19 17:12 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).