From: Roman.Perepelitsa on
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++?

First of all, I'm sure that the following is valid:
// foo is the same
int main()
{
int bar[foo::value];
}

And this one is not valid:
// foo is the same
int main()
{
const int& bar = foo::value;
}

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?

9.4.2 Static data members [class.static.data]

4
If a static data member is of const integral or const enumeration
type, its declaration in the class
definition can specify a constant-initializer which shall be an
integral constant expression (5.19). In that
case, the member can appear in integral constant expressions. The
member shall still be defined in a name-
space scope if it is used in the program and the namespace scope
definition shall not contain an initializer.

3.2 One definition rule [basic.def.odr]

2
An expression is potentially evaluated unless it appears where an
integral constant expression is required
(see 5.19), is the operand of the sizeof operator (5.3.3), or is the
operand of the typeid operator and
the expression does not designate an lvalue of polymorphic class type
(5.2.8). An object or non-overloaded
function is **used** if its name appears in a potentially-evaluated
expression.

Those are not enough to answer the question, hence I ask you for help.

Roman Perepelitsa.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 11 Apr., 19:34, "Roman.Perepeli...(a)gmail.com"
<Roman.Perepeli...(a)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! ]

From: Carl Barron on
In article
<c908380e-e078-4863-a31c-74ff14e9ff43(a)x41g2000hsb.googlegroups.com>,
Daniel Kr�gler <daniel.kruegler(a)googlemail.com> wrote:

> On 11 Apr., 19:34, "Roman.Perepeli...(a)gmail.com"
> <Roman.Perepeli...(a)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.

Strange interpretation:
so the value const in std::integral_constant<typename T, T v>::value
is not defined either!.

that is

// std headers not listed here

int main()
{
bool t = std::is_integral<double>::value; // is not define either!!!'
std::cout << t << '\n'; // t == 0 is it not??
//....
}

I seem to think there is something definitely wrong with this strange
interpretation. :)

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Alberto Ganesh Barbati on
Carl Barron ha scritto:
> In article
> <c908380e-e078-4863-a31c-74ff14e9ff43(a)x41g2000hsb.googlegroups.com>,
> Daniel Kr�gler <daniel.kruegler(a)googlemail.com> wrote:
>
>> On 11 Apr., 19:34, "Roman.Perepeli...(a)gmail.com"
>> <Roman.Perepeli...(a)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.
>
> Strange interpretation:
> so the value const in std::integral_constant<typename T, T v>::value
> is not defined either!.
>
> that is
>
> // std headers not listed here
>
> int main()
> {
> bool t = std::is_integral<double>::value; // is not define either!!!'
> std::cout << t << '\n'; // t == 0 is it not??
> //....
> }
>
> I seem to think there is something definitely wrong with this strange
> interpretation. :)
>

I don't see what would be wrong. Daniel Kr�gler's interpretation does
not say that the expression std::is_integral<double>::value is not
defined. It says that the evaluation of the *expression*
std::is_integral<double>::value does not require the definition of the
*object* std::is_integral<double>::value. That's because that the
absence of the definition does not affect the evaluation of the
expression, because the latter happens at compile time. Therefore,
there's no doubt that the t in your code will be initialized with a
value of false.

HTH,

Ganesh


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 12 Apr., 20:06, Carl Barron <cbarron...(a)adelphia.net> wrote:
> In article
> <c908380e-e078-4863-a31c-74ff14e9f...(a)x41g2000hsb.googlegroups.com>,
>
>
>
> Daniel Kr�gler <daniel.krueg...(a)googlemail.com> wrote:
> > On 11 Apr., 19:34, "Roman.Perepeli...(a)gmail.com"
> > <Roman.Perepeli...(a)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.
>
> Strange interpretation:
> so the value const in std::integral_constant<typename T, T v>::value
> is not defined either!.

I cannot follow your reasoning, mind to explain?

Just because [meta.help] does not *show* you a definition
for std::integral_constant<typename T, T v>::value is
not a proof, that it's definition is not needed.

A typical implementation looks like this (modulo namespace):

template <class T, T v>
struct integral_constant {
static const T value = v;
typedef T value_type;
typedef integral_constant<T,v> type;
};

template<class T, T v> const T integral_constant<T, v>::value;

For similar reasons you could argue that no definitions
of std::basic_string<..>::npos are required. But how can
the library implementor know, whether the user-code
takes e.g. a pointer or reference to this constant?
In this cases a definition of npos will be required
in both the current and the new C++ standard.

> that is
>
> // std headers not listed here
>
> int main()
> {
> bool t = std::is_integral<double>::value; // is not define either!!!'
> std::cout << t << '\n'; // t == 0 is it not??
> //....
>
> }
>
> I seem to think there is something definitely wrong with this strange
> interpretation. :)

As described above, the library implementation must
already provide a definition of std::is_integral<double>::value.
By including <type_traits> you have ensured that your
program contains the definition. Since std::is_integral
is a template, the compiler has to ensure that
the ODR is fulfilled, even if the program contains
multiple translation units that include <type_traits>,
see [basic.def.odr]/5:

"There can be more than one definition of a [..] static data
member of a class template (14.5.1.3), [..] in a program
provided that each definition appears in a different translation
unit, and provided the definitions satisfy the following
requirements[..]"

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! ]