From: Carl Barron on
In article
<1d29a464-41dc-4986-97f6-549943e2f015(a)b64g2000hsa.googlegroups.com>,
Daniel Kr�gler <daniel.kruegler(a)googlemail.com> wrote:

> 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
The point is
struct foo
{
static const int value = 1;
};

does not automatically violate ODR only different defintions of foo
would do so. The sniplet does not involve multiple defintions of foo
or
foo::value. and the sniplet is legal and valid.

--
[ 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 13 Apr., 20:45, Carl Barron <cbarron...(a)adelphia.net> wrote:
> The point is
> struct foo
> {
> static const int value = 1;
> };
>
> does not automatically violate ODR only different defintions of foo
> would do so. The sniplet does not involve multiple defintions of foo
> or
> foo::value. and the sniplet is legal and valid.

This is an incorrect/misleading statement as written. The
ODR is does not only rule *multiple* definitions, it does
also rule *missing* definitions. You can interpret that as
a *one-and-only-one-definition*. [basic.def.odr]/3 says
precisely this:

"Every program shall contain exactly one definition of
every non-inline function or object that is used in that
program; no diagnostic required. The definition can appear
explicitly in the program, it can be found in the standard
or a user-defined library, or (when appropriate) it is
implicitly defined (see 12.1, 12.4 and 12.8). An inline
function shall be defined in every translation unit in
which it is used."

For exactly this reason the whole (and quite long)
paragraph 2 defines the term "use". And the relevant
point which the OP points out is that the use-case

struct foo
{
static const int value = 1;
};

int main()
{
int bar = foo::value;
}

belongs to the category "use" in the current standard.
So there is a *use* *without* any definition and this is
a violation of the ODR and brings us into UB.

Neither the OP nor I did say, that every such example
violates the ODR. E.g. the example you provide in your
most recent answer does *not* violate the ODR as currently
visible (but it would require a complete program like

struct foo
{
static const int value = 1;
};

int main()
{
}

to discuss in a meaningful way about that point) and
the OP himself showed a use-case which does not require
a definition even according to the recent standard because
there is no "use". This was the example where the value of
foo::value appears as initialization value of an array-bound.
This was the reason of his quote of [basic.def.odr]/2:

"[..] An expression is potentially evaluated unless it
appears where an integral constant expression is required[..]"

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