Re: static const integral members
On 11 Apr., 19:34, "Roman.Perepeli...@gmail.com"
<Roman.Perepeli...@gmail.com> wrote:
I have a question regarding the following snippet of code.
struct foo
{
static const int value = 1;
};
int main()
{
int bar = foo::value;
}
Is it valid C++?
According to the wording of ISO 14882/2nd edition
this program violates the one definition rule,
because foo::value is not defined, but used, as
shown by the quotes you provided.
This has lead to the issue
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#48
and more relevant to your question to this one:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#454
The proposed resolution (which has now WP status and can be
found in the recent draft N2588), is to change the wording of
the offending paragraph here to say ([basic.def.odr]/2):
"[..] An object or non-overloaded function whose name appears as a
potentially-evaluated expression is used unless it is an object
that satisfies the requirements for appearing in a constant expression
(5.19) and the lvalue-to-rvalue conversion (4.1) is immediately
applied.[..]"
In your example
int bar = foo::value;
does fulfill the requirement for appearing in a constant expression,
even though bar itself does not fulfill that. This is strengthened
by the new wording in [expr.const]/2:
"A conditional-expression is a constant expression unless it involves
one of the following as a potentially evaluated subexpression[..]
[..]
an lvalue-to-rvalue conversion (4.1) unless it is applied to
-- an lvalue of integral type that refers to a non-volatile const
variable or static data member initialized with constant
expressions, or
-- an lvalue of literal type that refers to a non-volatile object
defined with constexpr, or that refers to a sub-object of such
an object;[..]"
First of all, I'm sure that the following is valid:
// foo is the same
int main()
{
int bar[foo::value];
}
Yes, this is fine, even in the wording of the current standard.
And this one is not valid:
// foo is the same
int main()
{
const int& bar = foo::value;
}
Correct.
But what about the first program in my post? Several respectful
C++ gurus (including Sutter and Straustrup) say that you can
use foo::value without definition if you don't take its address
and don't bind reference to it. But can it be confirmed by the
Standard?
Not yet, but in the corrected version, if the above described
issue is accepted.
Those are not enough to answer the question, hence I ask you for help.
<nod>, I hope that answer was satisfactory.
Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]