Topic: Why no floating-point non-type template parameters?


Author: Matthew Austern <austern@research.att.com>
Date: Mon, 30 Jul 2001 20:44:06 GMT
Raw View
Pete Becker <petebecker@acm.org> writes:

> Niklas Matthies wrote:
> >
> > I still don't understand what you meant to express with your reply (the
> > one I marked with *'s above).
> >
>
> The example that Howard posted was, in part, this:
>
> std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';
>
> In order for the template parameter to be a valid non-type argument it
> must be a compile-time constant. The language definition does not
> require compilers to evaluate expressions that involve floating point
> values at compile time.

Actually, Pete, I think you could make a stronger statement than that.
The non-type template argument must be an integer constant-expression.
(Or one of a small list of other things, like the address of an object
with external linkage.)

"1.0 == 1.00000000001" is not an integer constant-expression.  I
believe a diagnostic is required.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Noah Stein" <noah@vision-scape.com>
Date: Tue, 31 Jul 2001 11:14:44 GMT
Raw View
>std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';

> Actually, Pete, I think you could make a stronger statement than that.
> The non-type template argument must be an integer constant-expression.
> (Or one of a small list of other things, like the address of an object
> with external linkage.)
>
> "1.0 == 1.00000000001" is not an integer constant-expression.  I
> believe a diagnostic is required

I think it is permissible.

14.3.2.1 states that a "template-argument for a non-type, non-template
template-parameter shall be one of - an integral constant-expression of
integral or enumeration type...".

3.9.1.7 states that "Types bool, ... and the signed and unsigned integer
types are collectively called integral types."

5.9.1 states that relational operators "all yield false or true.  The type
of the result is bool."

So, the == relation will result in a bool; a valid type for a non-type,
non-template template-parameter.  Therefore, the original expression is
valid because the values are constant at the time of compilation.  Of
course, the utility of such an expression is highly dubious due to the
reasons already cited for disallowing the inclusion of floating-point
non-type, non-template template paramters.

-- Noah


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 31 Jul 2001 17:06:11 GMT
Raw View
Noah Stein wrote:
...
> > "1.0 == 1.00000000001" is not an integer constant-expression.  I
> > believe a diagnostic is required
>
> I think it is permissible.
>
> 14.3.2.1 states that a "template-argument for a non-type, non-template
> template-parameter shall be one of - an integral constant-expression of
> integral or enumeration type...".

This is one of those cases where a phrase that you would naively think
has one meaning, is actually defined by the standard to have a somewhat
different meaning. Integral constant-expressions are not just
expressions with an itegral type and a constant value. 5.19p2 says that
floating point literals are allowed in integral constant expressions
only if they are converted to integral or enumeration types.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: James Dennett <jdennett@acm.org>
Date: Tue, 31 Jul 2001 18:39:06 GMT
Raw View
Noah Stein wrote:
>
> >std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';
>
> > Actually, Pete, I think you could make a stronger statement than that.
> > The non-type template argument must be an integer constant-expression.
> > (Or one of a small list of other things, like the address of an object
> > with external linkage.)
> >
> > "1.0 == 1.00000000001" is not an integer constant-expression.  I
> > believe a diagnostic is required
>
> I think it is permissible.
>
> 14.3.2.1 states that a "template-argument for a non-type, non-template
> template-parameter shall be one of - an integral constant-expression of
> integral or enumeration type...".
>
> 3.9.1.7 states that "Types bool, ... and the signed and unsigned integer
> types are collectively called integral types."
>
> 5.9.1 states that relational operators "all yield false or true.  The type
> of the result is bool."
>
> So, the == relation will result in a bool; a valid type for a non-type,
> non-template template-parameter.  Therefore, the original expression is
> valid because the values are constant at the time of compilation.  Of
> course, the utility of such an expression is highly dubious due to the
> reasons already cited for disallowing the inclusion of floating-point
> non-type, non-template template paramters.

Almost right, but an "integral constant-expression" is more strictly
defined than that.  (1.0 == 1.0) is not a constant-expression according
to the definitions of the Standard.  Constant-expression does allow for
floating point arithmetic; 5.19 says that "Floating literals (2.13.3)
can appear only if they are cast to integral or enumeration types."

-- James Dennett

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Tue, 31 Jul 2001 21:23:43 GMT
Raw View
Noah Stein wrote:
>
> >std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';
>
> > Actually, Pete, I think you could make a stronger statement than that.
> > The non-type template argument must be an integer constant-expression.
> > (Or one of a small list of other things, like the address of an object
> > with external linkage.)
> >
> > "1.0 == 1.00000000001" is not an integer constant-expression.  I
> > believe a diagnostic is required
>
> I think it is permissible.
>
> 14.3.2.1 states that a "template-argument for a non-type, non-template
> template-parameter shall be one of - an integral constant-expression of
> integral or enumeration type...".
>
> 3.9.1.7 states that "Types bool, ... and the signed and unsigned integer
> types are collectively called integral types."
>
> 5.9.1 states that relational operators "all yield false or true.  The type
> of the result is bool."
>
> So, the == relation will result in a bool; a valid type for a non-type,
> non-template template-parameter.  Therefore, the original expression is
> valid because the values are constant at the time of compilation.  Of
> course, the utility of such an expression is highly dubious due to the
> reasons already cited for disallowing the inclusion of floating-point
> non-type, non-template template paramters.
>

But there's also 5.19/1:

 An integral constant-expression can involve only
 literals (2.13), enumerators, const variables or
 static data members of integral or enumeration types
 initialized with constant expressions (8.5), non-type
 template parameters of integral or enumeration types,
 and sizeof expressions. Floating literals (2.13.3) can
 appear only if they are cast to integral or enumeration
 types.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Howard Hinnant <hinnant@antispam.twcny.rr.com>
Date: Fri, 3 Aug 2001 02:32:10 GMT
Raw View
In article <3b616b73.24039043@news.libero.it>, Gennaro Prota
<gennaro_prota@my-deja.com> wrote:

| template <double X> class Foo { ... };
|      typedef Foo<1.0/3.0> Barx;
|      typedef Foo<1.1/3.3> Zapx;
|
| Barx and Zapx are the same type or not?

Fwiw, assuming floating types could be used like this, boost::is_same
could be used to make this code portable:

static const bool isFooSame = is_same<Barx, Zapx>::value;

| So the floating-point limitation is very very puzzling for me... :-)
| What do you think about that?

Not puzzling for me.  But I still disagree with the limitation (and
agree with you).  I would like to see the limitation lifted.  And still
not holding my breath. :-)

--
Howard Hinnant

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gennaro_prota@my-deja.com (Gennaro Prota)
Date: Fri, 3 Aug 2001 11:49:58 GMT
Raw View
Ok, but can you put some light about the following code using a
reference to double  as template parameter?


double x = 1.0;
double y = 1.0000000001;

template <double& X>
class Foo {
        // ...
};

int main (int, char*)
{
 Foo<x> f1;
 Foo<y> f2;

return 0;
}

On platforms where  x and y gets initialized with the same value are
Foo<x> and Foo<y> the same type? I'm not sure about that, but I
suspect they are different types anyway, otherwise why allow double&
but not double? Could you tell me where the standard gives such a
rule, if any? :-)


  Thanks,
     Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Sat, 4 Aug 2001 05:53:40 GMT
Raw View
Gennaro Prota wrote:
>
> Ok, but can you put some light about the following code using a
> reference to double  as template parameter?
>
> double x = 1.0;
> double y = 1.0000000001;
>
> template <double& X>
> class Foo {
>         // ...
> };
>
> int main (int, char*)
> {
>         Foo<x> f1;
>         Foo<y> f2;
>
> return 0;
> }
>
> On platforms where  x and y gets initialized with the same value are
> Foo<x> and Foo<y> the same type? I'm not sure about that, but I
> suspect they are different types anyway, otherwise why allow double&
> but not double? Could you tell me where the standard gives such a
> rule, if any? :-)

Section 14.4p1: "Two _template-id_s refer to the same class or function
if ... their non-type _template-arguments_ of pointer or reference type
refer to the same external object ..."

'x' and 'y' don't refer to the same external object, so Foo<x> and
Foo<y> are different template ids.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Paul Mensonides" <pmenso57@home.com>
Date: Fri, 27 Jul 2001 09:33:43 GMT
Raw View
how about this...

#include<iostream>

template<class T> class dbl_p {
    public:
        static const double i = T::value;
};

const double x = 1.23456;
const double y = 1.23456;

struct xy {
    static const double value = x * y;
};

int main() {
    std::cout << dbl_p<xy>::i << std::endl;
    return 0;
}

Paul Mensonides


"Matthew Austern" <austern@research.att.com> wrote in message
news:dilu1zzcmag.fsf@isolde.research.att.com...
> Howard Hinnant <hinnant@antispam.twcny.rr.com> writes:
>
> > Actually I can do this with my current system.  I'm not a language
> > lawyer so I may be depending on an extension to the language without
> > realizing it.
> >
> > #include <iostream>
> >
> > template <int I>
> > struct int2type  // *
> > {
> >    static int const value = I;
> > };
> >
> > int main()
> > {
> >    std::cout << int2type<1.0 == 1.000000001>::value << '\n';
> >    std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';
> > }
>
> I think you are depending on an extension, yes.  14.3.2, paragraph
> 1, is a complete list of the things you can pass as non-type
> template arguments.  The only one that could possibly fit in this
> case is the first bullet item: "an integral constant-expression of
> integral or enumeration type".
>
> Integral constant expressions are defined in 5.19, paragraph 1.
> If I'm reading that paragraph correctly, then the expression
> "1.0 == 1.000000001" does not qualify as an integral constant-
> expression.
>
> Here's the relevant quote.  Note especially the second sentence:
>
>    An integral constant-expression can involve only
>    literals, enumerators, const variables or static data
>    members of integral or enumeration types initialized with
>    constant expression, non-type template parameters of
>    integral or enumeration types, and sizeof expressions
>    expressions.  Floating literals can appear only if they
>    are cast to integral or enumeration types.
>
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Fri, 27 Jul 2001 17:02:30 GMT
Raw View
"Paul Mensonides" <pmenso57@home.com> writes:

| how about this...
|
| #include<iostream>
|
| template<class T> class dbl_p {
|     public:
|         static const double i = T::value;
| };
|
| const double x = 1.23456;
| const double y = 1.23456;
|
| struct xy {
|     static const double value = x * y;
| };

Invalid.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gennaro_prota@my-deja.com (Gennaro Prota)
Date: Fri, 27 Jul 2001 17:02:48 GMT
Raw View
Sorry for not having checked it before posting, but there were
previous threads about this subject on comp.std.c++.

I've just read one of them ("non-type template-parameter types ",
Date: 2001-03-01 10:20:10 PST) and substantially I agree with Dennis
Yelle's idea: who cares whether, given

template <double X> class Foo { ... };
     typedef Foo<1.0/3.0> Barx;
     typedef Foo<1.1/3.3> Zapx;

Barx and Zapx are the same type or not?

Ok, I hear your complaints... :-) There are situations where it cares
if two template class instances are of the same type or not, for
instance, if you want to do an assignment like:

Foo <1> f1;
Foo <1.00000000000001> f2;

f2 = f1

and the only Foo's assignment operator is

Foo<X>& operator = (Foo<X> o); // copy  assignment only

(because Foo's semanthic only allows copy when template arguments used
for f1 and f2 have the same value).

In such a case you end up with code that compiles under some platforms
and doesn't under others; I admit that this is quite unusual in the
sense that implementation-dependent code normally behaves differently
at run-time  but does compile independently from the target platform.
Anyhow, this doesn't seem to me a good reason to prohibit
floating-point template parameters at all, also considering that you
can have the same situation with code like:

template <char* p> class Foo { ... };

    char s1[] = "Foobar";
    char s2[] = "Foobar";

Foo<s1> and Foo<s2> may be the same type or not, am I right?

Moreover, since you can use a reference as template parameter you can
have the same "problem" with code like this (perfectly legal):

double x = 1.0;
double y = 1.0000000001;

template <double& X>
class Foo {
        // ...
};

int main (int, char*)
{
 Foo<x> f1;
 Foo<y> f2;

return 0;
}

So the floating-point limitation is very very puzzling for me... :-)
What do you think about that?

> Furthermore, which pairs of nominally different numbers
>are distinguished from each other, and which pairs are identical. A
>further complication is that the limits might be different in the
>translation environment and in the execution environment
>(cross-compilation).

So what is the behavior of a cross-compiler if you write for instance:

double d = 1.1*5.3;

Does it avoid constant folding and postpone the computation at
run-time?


   Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Howard Hinnant <hinnant@antispam.twcny.rr.com>
Date: Fri, 27 Jul 2001 17:37:12 GMT
Raw View
In article <fl1yn38ih3.fsf@jambon.cmla.ens-cachan.fr>, Gabriel Dos Reis
<dosreis@cmla.ens-cachan.fr> wrote:

| Even then how, in Standardese, could one tell the program translator
| to use this or that rounding mode?

Should the committee wish to entertain floating point compile time
computation, this doesn't seem insurmountable.  Seems like a pragma
could take care of this.  To be ignored of course if the target
environment didn't support rounding modes.

--
Howard Hinnant

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2001-10-01@nmhq.net (Niklas Matthies)
Date: Fri, 27 Jul 2001 17:40:02 GMT
Raw View
On Fri, 27 Jul 2001 01:06:51 GMT, Pete Becker <petebecker@acm.org> wrote:
> Niklas Matthies wrote:
> > On Thu, 26 Jul 2001 19:55:35 GMT, Pete Becker <petebecker@acm.org> wrote:
> > > Howard Hinnant wrote:
> > > > In article <3B601115.A592E13F@acm.org>, Pete Becker <petebecker@acm.org> wrote:
> > > > | Howard Hinnant wrote:
> > > > | >
> > > > | > Can't the same argument be made against integral types?
> > > > |
> > > > | The difference is that with integral types you can test at compile
> > > > | time | whether the values are the same.
> > > >
> > > > Actually I can do this with my current system.  I'm not a language
> > > > lawyer so I may be depending on an extension to the language without
> > > > realizing it.
> > >
> > > It's not technically an extension. Under the as-if rule the compiler is
> > > permitted to fold floating point arithmetic operations. But it's not
> > > required to, so that's definitely not portable.
> >
> > Does that mean that a compiler that chooses to not perform
> > floating-point computations at compile time is required to perform
> > template instantiation at run-time?
>
> No, it's the reason that floating point values aren't allowed as
> template non-type arguments.

You gave the impression that the example under discussion was legal C++.
Since apparently it isn't legal C++, talking about "not technically an
extension" and the as-if-rule doesn't make too much sense.

-- Niklas Matthies
--
Less matters that which you can take by yourself than that which others
have given to you.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Fri, 27 Jul 2001 17:55:31 GMT
Raw View
Niklas Matthies wrote:
>
> On Fri, 27 Jul 2001 01:06:51 GMT, Pete Becker <petebecker@acm.org> wrote:
> > Niklas Matthies wrote:
> > > On Thu, 26 Jul 2001 19:55:35 GMT, Pete Becker <petebecker@acm.org> wrote:
> > > > Howard Hinnant wrote:
> > > > > In article <3B601115.A592E13F@acm.org>, Pete Becker <petebecker@acm.org> wrote:
> > > > > | Howard Hinnant wrote:
> > > > > | >
> > > > > | > Can't the same argument be made against integral types?
> > > > > |
> > > > > | The difference is that with integral types you can test at compile
> > > > > | time | whether the values are the same.
> > > > >
> > > > > Actually I can do this with my current system.  I'm not a language
> > > > > lawyer so I may be depending on an extension to the language without
> > > > > realizing it.
> > > >
> > > > It's not technically an extension. Under the as-if rule the compiler is
> > > > permitted to fold floating point arithmetic operations. But it's not
> > > > required to, so that's definitely not portable.
> > >
> > > Does that mean that a compiler that chooses to not perform
> > > floating-point computations at compile time is required to perform
> > > template instantiation at run-time?
> >
> > No, it's the reason that floating point values aren't allowed as
> > template non-type arguments.
>
> You gave the impression that the example under discussion was legal C++.
> Since apparently it isn't legal C++, talking about "not technically an
> extension" and the as-if-rule doesn't make too much sense.
>

This thread is about why floating point values aren't permitted as
non-type parameters. Take a look at the words you quoted for the context
of this subthread: it's about compile-time comparisons of floating point
values.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Fri, 27 Jul 2001 18:00:09 GMT
Raw View
Paul Mensonides wrote:
>
> how about this...
>
> #include<iostream>
>
> template<class T> class dbl_p {
>     public:
>         static const double i = T::value;
> };
>
> const double x = 1.23456;
> const double y = 1.23456;
>
> struct xy {
>     static const double value = x * y;
> };
>
> int main() {
>     std::cout << dbl_p<xy>::i << std::endl;
>     return 0;
> }
>

It's illegal. You can't initialize a double member within the class
definition. The initializatoin of 'value' isn't allowed.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2001-10-01@nmhq.net (Niklas Matthies)
Date: Fri, 27 Jul 2001 18:51:01 GMT
Raw View
On Fri, 27 Jul 2001 17:55:31 GMT, Pete Becker <petebecker@acm.org> wrote:
> Niklas Matthies wrote:
> > On Fri, 27 Jul 2001 01:06:51 GMT, Pete Becker <petebecker@acm.org> wrote:
> > > Niklas Matthies wrote:
> > > > On Thu, 26 Jul 2001 19:55:35 GMT, Pete Becker <petebecker@acm.org> wrote:
> > > > > Howard Hinnant wrote:
> > > > > > In article <3B601115.A592E13F@acm.org>, Pete Becker <petebecker@acm.org> wrote:
> > > > > > | Howard Hinnant wrote:
> > > > > > | >
> > > > > > | > Can't the same argument be made against integral types?
> > > > > > |
> > > > > > | The difference is that with integral types you can test at compile
> > > > > > | time | whether the values are the same.
> > > > > >
> > > > > > Actually I can do this with my current system.  I'm not a
> > > > > > language lawyer so I may be depending on an extension to the
> > > > > > language without realizing it.
> > > > >
>*> > > > It's not technically an extension. Under the as-if rule the
>*> > > > compiler is permitted to fold floating point arithmetic
>*> > > > operations. But it's not required to, so that's definitely not
>*> > > > portable.
> > > >
> > > > Does that mean that a compiler that chooses to not perform
> > > > floating-point computations at compile time is required to perform
> > > > template instantiation at run-time?
> > >
> > > No, it's the reason that floating point values aren't allowed as
> > > template non-type arguments.
> >
> > You gave the impression that the example under discussion was legal C++.
> > Since apparently it isn't legal C++, talking about "not technically an
> > extension" and the as-if-rule doesn't make too much sense.
>
> This thread is about why floating point values aren't permitted as
> non-type parameters. Take a look at the words you quoted for the context
> of this subthread: it's about compile-time comparisons of floating point
> values.

I still don't understand what you meant to express with your reply (the
one I marked with *'s above).

-- Niklas Matthies
--
The problem about having an open mind, of course, is that people will
insist on coming along and trying to put things in it.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Fri, 27 Jul 2001 23:04:45 GMT
Raw View
Howard Hinnant <hinnant@antispam.twcny.rr.com> writes:

| In article <fl1yn38ih3.fsf@jambon.cmla.ens-cachan.fr>, Gabriel Dos Reis
| <dosreis@cmla.ens-cachan.fr> wrote:
|
| | Even then how, in Standardese, could one tell the program translator
| | to use this or that rounding mode?
|
| Should the committee wish to entertain floating point compile time
| computation, this doesn't seem insurmountable.

I have no doubt that the committee could invent anything it likes.

But this :

|  Seems like a pragma
| could take care of this.  To be ignored of course if the target
| environment didn't support rounding modes.

by itself, is a sufficent reason to reconsider the issue.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Fri, 27 Jul 2001 20:04:26 CST
Raw View
Niklas Matthies wrote:
>
> I still don't understand what you meant to express with your reply (the
> one I marked with *'s above).
>

The example that Howard posted was, in part, this:

std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';

In order for the template parameter to be a valid non-type argument it
must be a compile-time constant. The language definition does not
require compilers to evaluate expressions that involve floating point
values at compile time.

I see that what I said was a bit broader than I intended. In an
expression like

if (1.0 == 1.0000000000000000001)
 std::cout << "equal\n";
else
 std::cout << "not equal\n";

the compiler could (with full knowledge of fp math on the target system)
do the equality comparison at compile time, eliminating the appropriate
branch of the if, without affecting the meaning of the program. That's
all I meant to say under the rubric of the as-if rule.

In the context of the template example the as-if rule isn't applicable.
The expression isn't what the standard defines as a compile-time
constant, so the template instantiation is illegal. Allowing it involves
two things: first, compile-time evaluation of floating point expressions
(permissible under the as-if rule) and second, treating the result of
such an evaluation as a compile-time constant. The latter is an
extension, and would be permitted if the compiler issued a diagnostic
when it did it. Without a diagnostic it's not valid.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Paul Mensonides" <pmenso57@home.com>
Date: Sat, 28 Jul 2001 10:07:44 GMT
Raw View
"Pete Becker" <petebecker@acm.org> wrote in message
news:3B6177A7.6190B06B@acm.org...
> Paul Mensonides wrote:
> >
> > how about this...
> >
> > #include<iostream>
> >
> > template<class T> class dbl_p {
> >     public:
> >         static const double i = T::value;
> > };
> >
> > const double x = 1.23456;
> > const double y = 1.23456;
> >
> > struct xy {
> >     static const double value = x * y;
> > };
> >
> > int main() {
> >     std::cout << dbl_p<xy>::i << std::endl;
> >     return 0;
> > }
> >
>
> It's illegal. You can't initialize a double member within the class
> definition. The initializatoin of 'value' isn't allowed.

My mistake.  I use VC++ so I can't do it with integral types anyway.

---------- file.cpp ----------

#include <iostream>

const double x = 1.23456;
const double y = 1.23456;

template<class T> class dbl_p {
    public:
        static const double i;
};

template<class T> const double dbl_p<T>::i = T::value;

struct xy {
    static const double value;
};

const double xy::value = x * y;

int main() {
    std::cout << dbl_p<xy>::i << std::endl;
    return 0;
}

----------

Even VC++ compiles this!

Paul Mensonides

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Stephen Clamage <stephen.clamage@sun.com>
Date: Sun, 29 Jul 2001 02:25:36 GMT
Raw View
On Fri, 27 Jul 2001 17:02:48 GMT, gennaro_prota@my-deja.com (Gennaro
Prota) wrote:

>Sorry for not having checked it before posting, but there were
>previous threads about this subject on comp.std.c++.
>
>I've just read one of them ("non-type template-parameter types ",
>Date: 2001-03-01 10:20:10 PST) and substantially I agree with Dennis
>Yelle's idea: who cares whether, given
>
>template <double X> class Foo { ... };
>     typedef Foo<1.0/3.0> Barx;
>     typedef Foo<1.1/3.3> Zapx;
>
>Barx and Zapx are the same type or not?
>
>Ok, I hear your complaints... :-) ...
>In such a case you end up with code that compiles under some platforms
>and doesn't under others;

That isn't the only problem. You can also wind up with code that
compiles with one compiler on the platform but not with a different
compiler on the same platform. (Small differences in FP arithmetic at
compile time.)

Worse, the code might compile error-free with two different
implementations, but produce different results.

The usual complaint about C++ is that too many features are
implementation-defined, making it hard to write portable code. This
proposal would increase the amount of implementation-defined results.


---
Steve Clamage, stephen.clamage@sun.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gennaro_prota@my-deja.com (Gennaro Prota)
Date: Sun, 29 Jul 2001 18:05:06 GMT
Raw View
On Sun, 29 Jul 2001 02:25:36 GMT, Stephen Clamage
<stephen.clamage@sun.com> wrote:


>That isn't the only problem. You can also wind up with code that
>compiles with one compiler on the platform but not with a different
>compiler on the same platform. (Small differences in FP arithmetic at
>compile time.)
>
>Worse, the code might compile error-free with two different
>implementations, but produce different results.
>
>The usual complaint about C++ is that too many features are
>implementation-defined, making it hard to write portable code. This
>proposal would increase the amount of implementation-defined results.
>
>
Ok, that's true; I can't say how many times I wondered why the details
of this or that feature were leaved to the implementation, but I never
thought that it would have been a solution to get rid of the feature
at all! ;-)
Anyhow, what about my examples using char pointers and references to
doubles? Am I missing something?

     Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Sun, 29 Jul 2001 22:35:47 GMT
Raw View
Paul Mensonides wrote:
>
> ---------- file.cpp ----------
>
> #include <iostream>
>
> const double x = 1.23456;
> const double y = 1.23456;
>
> template<class T> class dbl_p {
>     public:
>         static const double i;
> };
>
> template<class T> const double dbl_p<T>::i = T::value;
>
> struct xy {
>     static const double value;
> };
>
> const double xy::value = x * y;
>
> int main() {
>     std::cout << dbl_p<xy>::i << std::endl;
>     return 0;
> }
>
> ----------
>
> Even VC++ compiles this!
>

And gcc compiles it as well! Remarkable! <g> But this is pretty basic
template stuff. In particular, it doesn't involve floating-point
non-type template parameters. What is it supposed to demonstrate?

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2001-10-01@nmhq.net (Niklas Matthies)
Date: Mon, 30 Jul 2001 03:36:38 GMT
Raw View
On Fri, 27 Jul 2001 20:04:26 CST, Pete Becker <petebecker@acm.org> wrote:
> Niklas Matthies wrote:
> >=20
> > I still don't understand what you meant to express with your reply (t=
he
> > one I marked with *'s above).
> >=20
>=20
> The example that Howard posted was, in part, this:
>=20
> std::cout << int2type<1.0 =3D=3D 1.0000000000000000001>::value << '\n';
[=B7=B7=B7]
> In the context of the template example the as-if rule isn't applicable.
> The expression isn't what the standard defines as a compile-time
> constant, so the template instantiation is illegal. Allowing it involve=
s
> two things: first, compile-time evaluation of floating point expression=
s
> (permissible under the as-if rule) and second, treating the result of
> such an evaluation as a compile-time constant. The latter is an
> extension, and would be permitted if the compiler issued a diagnostic
> when it did it. Without a diagnostic it's not valid.

Ok, thanks for clarifying.

-- Niklas Matthies
--=20
There are no happy endings, for nothing ever ends.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Paul Mensonides" <pmenso57@home.com>
Date: Mon, 30 Jul 2001 10:30:50 GMT
Raw View
"Pete Becker" <petebecker@acm.org> wrote in message
news:3B6420E6.E4C9DBAB@acm.org...
> Paul Mensonides wrote:
> >
> > ---------- file.cpp ----------
> >
> > #include <iostream>
> >
> > const double x = 1.23456;
> > const double y = 1.23456;
> >
> > template<class T> class dbl_p {
> >     public:
> >         static const double i;
> > };
> >
> > template<class T> const double dbl_p<T>::i = T::value;
> >
> > struct xy {
> >     static const double value;
> > };
> >
> > const double xy::value = x * y;
> >
> > int main() {
> >     std::cout << dbl_p<xy>::i << std::endl;
> >     return 0;
> > }
> >
> > ----------
> >
> > Even VC++ compiles this!
> >
>
> And gcc compiles it as well! Remarkable! <g> But this is pretty basic
> template stuff. In particular, it doesn't involve floating-point
> non-type template parameters. What is it supposed to demonstrate?

It just generates a constant.  You can specialize the template with a specific
"value":

template<> class dbl_p<xy> {
    // ...
};

Granted, you don't get the same "type" directly...

--------------------

#include <typeinfo>

const double a = 2.0;
const double b = 10.0;
const double x = 4.0;
const double y = 5.0;

struct AB {
    static const double val;
};

struct XY {
    static const double val;
};

const double AB::val = a * b; // 20.0
const double XY::val = x * y; // 20.0

template<class T, class U> class Comp {
    public:
        static const bool res;
};

template<class T, class U> const bool Comp<T, U>::res = T::val == U::val;

template<bool B> class Kill;
template<> class Kill<true> { };

template<class T, template<class, class> class C = Comp> class Test {
    private:
        int m_x, m_y;
    public:
        Test(int x, int y) : m_x(x), m_y(y) {
            return;
        }
        template<class U> operator Test<U>(void) {
            if (C<T, U>::res) {
                return Test<U>(x, y);
            }
            else {
                throw std::bad_cast();

                // I tried this, (to cause the code to not compile)

                // throw Kill<C<T, U>::res>();

                // but Comeau didn't recognize
                // C<T, U>::res as a compile-time constant value
            }
        }
};

void f(Test<AB>) {
    return;
}

void g(Test<XY>) {
    return;
}

int main(void) {
    Test<AB> ab(1, 2);
    g(ab);
    Test<XY> xy(3, 4);
    f(xy);
    return 0;
}
--------------------
Paul Mensonides

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gennaro_prota@my-deja.com (Gennaro Prota)
Date: Wed, 25 Jul 2001 21:06:45 GMT
Raw View
Hi everybody,

may I know what is the rationale for clause 14.1p7:

"A non-type template-parameter shall not be declared to have floating
point, class, or void type." ?

Actually I never worried about that limitation, until I had the idea
of implementing a class template to compute square roots at compile
time. (Newton's method). Obviusly my intention was to use recursive
template instantiation and a template parameter of type double. :-)

   Genny.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Thu, 26 Jul 2001 01:22:16 GMT
Raw View
Gennaro Prota wrote:
>
> Hi everybody,
>
> may I know what is the rationale for clause 14.1p7:
>
> "A non-type template-parameter shall not be declared to have floating
> point, class, or void type." ?
>

Text representations of floating point values (i.e. compile-time
constants) don't necessarily have the same value on different systems.
So it would be far too easy to accidentally write non-portable code if
this were allowed.

template<float f> class C
{
};

void f(C<1.00000001>)
 {
 }

void f(C<1.00000000>)
 {
 }

Are the two argument types different (in which case the code is legal)
or the same (in which case it's illegal)?

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Howard Hinnant <hinnant@antispam.twcny.rr.com>
Date: Thu, 26 Jul 2001 05:31:36 GMT
Raw View
In article <3B5F6B2A.C15B6777@acm.org>, Pete Becker
<petebecker@acm.org> wrote:

| Text representations of floating point values (i.e. compile-time
| constants) don't necessarily have the same value on different systems.
| So it would be far too easy to accidentally write non-portable code if
| this were allowed.
|
| template<float f> class C
| {
| };
|
| void f(C<1.00000001>)
|         {
|         }
|
| void f(C<1.00000000>)
|         {
|         }
|
| Are the two argument types different (in which case the code is legal)
| or the same (in which case it's illegal)?

Can't the same argument be made against integral types?

template<short f> class C
{
};

void f(C<65536>)
        {
        }

void f(C<0>)
        {
        }

Portable?

Personally I think that given that the C++ template system is a fully
functional compile time computation mechanism, it is a shame that
compile time floating point computation (which is generally done
anyway) is excluded.

Agreed one would need to know what one is doing.  But I appreciate the
general philosophy and freedom of C and C++ :  here's the nuclear
weapon, please try not to blow yourself up.

--
Howard Hinnant

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Thu, 26 Jul 2001 16:27:24 GMT
Raw View
Howard Hinnant wrote:
>
> Can't the same argument be made against integral types?
>

The difference is that with integral types you can test at compile time
whether the values are the same.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Thu, 26 Jul 2001 16:27:32 GMT
Raw View
Howard Hinnant <hinnant@antispam.twcny.rr.com> writes:

| | Are the two argument types different (in which case the code is legal)
| | or the same (in which case it's illegal)?
|
| Can't the same argument be made against integral types?

Hmm, for floating point types, it is more than that: which rouding
mode is in choosen? And how can it be selected?  Shall the
implementation use gradual over/underflow?

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 26 Jul 2001 17:32:53 GMT
Raw View
Howard Hinnant wrote:
>
> In article <3B5F6B2A.C15B6777@acm.org>, Pete Becker
> <petebecker@acm.org> wrote:
>
> | Text representations of floating point values (i.e. compile-time
> | constants) don't necessarily have the same value on different systems.
> | So it would be far too easy to accidentally write non-portable code if
> | this were allowed.
> |
> | template<float f> class C
> | {
> | };
> |
> | void f(C<1.00000001>)
> |         {
> |         }
> |
> | void f(C<1.00000000>)
> |         {
> |         }
> |
> | Are the two argument types different (in which case the code is legal)
> | or the same (in which case it's illegal)?
>
> Can't the same argument be made against integral types?

No. The fundamental difference between floating point and integral types
is that arbitrary small differences aren't necessarily representable. By
definition, the smallest non-zero difference between two integral values
is 1, and that's always representable.

There is no non-zero limit on the difference between two floating point
values; whereas there is an implementation-defined value dependent
non-zero limit on the difference between two representable floating
point values. Furthermore, which pairs of nominally different numbers
are distinguished from each other, and which pairs are identical. A
further complication is that the limits might be different in the
translation environment and in the execution environment
(cross-compilation).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Howard Hinnant <hinnant@antispam.twcny.rr.com>
Date: Thu, 26 Jul 2001 19:47:35 GMT
Raw View
In article <3B601115.A592E13F@acm.org>, Pete Becker
<petebecker@acm.org> wrote:

| Howard Hinnant wrote:
| >
| > Can't the same argument be made against integral types?
| >
|
| The difference is that with integral types you can test at compile time
| whether the values are the same.

Actually I can do this with my current system.  I'm not a language
lawyer so I may be depending on an extension to the language without
realizing it.

#include <iostream>

template <int I>
struct int2type  // *
{
   static int const value = I;
};

int main()
{
   std::cout << int2type<1.0 == 1.000000001>::value << '\n';
   std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';
}

On my system this prints out:
0
1

(*my respects to Andrei for shamelessly hijacking part of Loki :-) )

In article <flelr3on3e.fsf@jambon.cmla.ens-cachan.fr>, Gabriel Dos Reis
<dosreis@cmla.ens-cachan.fr> wrote:

| Hmm, for floating point types, it is more than that: which rouding
| mode is in choosen? And how can it be selected?  Shall the
| implementation use gradual over/underflow?

Good questions.  And I would think the answers would be implementation
dependent.  My system clearly does floating point computation at
compile time, even though you can not instantiate templates with
floating point types.  To the best of my knowledge, the compiler uses
the default floating point system of the target environment.  For
example:

double x = 2*1.5;

Examining the assembly generated by this statement reveals that 3.0 is
directly assigned (instead of multiplying 2. by 1.5 and assigning the
result).

My system appears to be using IEEE round to nearest.  This:

   std::cout << int2type<1.0 == 1.0/3.0 * 3.0>::value << '\n';

outputs 1 for me (Metrowerks on PowerPC).  I would be most interested
in knowing what it outputs for others (if it compiles).

In article <3B601051.DBFD61B3@wizard.net>, James Russell Kuyper Jr.
<kuyper@wizard.net> wrote:

I apologize, but I am just not groking the point of most of your
message.  Maybe I've just had too much caffine today ... maybe not
enough.

| A
| further complication is that the limits might be different in the
| translation environment and in the execution environment
| (cross-compilation).

I am aware that the Metrowerks cross compilers are very careful to
emulate the floating point environment of the target when doing
cross-compile compile-time floating point computation.

I understand the reasoning behind the ban on floating types in
templates.  I'm just not sure I agree with it.  Floating types can be
viewed as just a container for a finite set of discrete values, just as
integral types are ... Just bit buckets with their own rules for + - *
/.

I would also be most interested in being able to define floating point
constants in classes:

struct A
{
   static double const pi = 3.14;
};

Or even cooler, adopt C99's hex floating format:

struct A
{
   static double const x = 0x1.8p0;
};

Just think how much more useful numeric_limits could be if max() and
min() were static data members instead of methods!

Yes I think there's a lot of neat problems that could be elegantly
solved if floating point wasn't a second class citizen at compile time.
It might not be very portable (like type_info).  And it might be prone
to abuse in the hands of the inexperienced (like heap memory).  But
personally I would appreciate the expressive power (as opposed to the
work arounds I currently perform to work with floating point values at
compile time).

However I'm not holding my breath on this one. ;-)

--
Howard Hinnant

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Thu, 26 Jul 2001 19:55:35 GMT
Raw View
Howard Hinnant wrote:
>
> In article <3B601115.A592E13F@acm.org>, Pete Becker
> <petebecker@acm.org> wrote:
>
> | Howard Hinnant wrote:
> | >
> | > Can't the same argument be made against integral types?
> | >
> |
> | The difference is that with integral types you can test at compile time
> | whether the values are the same.
>
> Actually I can do this with my current system.  I'm not a language
> lawyer so I may be depending on an extension to the language without
> realizing it.
>

It's not technically an extension. Under the as-if rule the compiler is
permitted to fold floating point arithmetic operations. But it's not
required to, so that's definitely not portable.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Thu, 26 Jul 2001 21:13:21 GMT
Raw View
Howard Hinnant wrote:
>
> Personally I think that given that the C++ template system is a fully
> functional compile time computation mechanism, it is a shame that
> compile time floating point computation (which is generally done
> anyway) is excluded.
>

C doesn't support floating point math in the preprocessor because that
would require compile-time emulation of floating point math for the
target system, which could be very expensive for a cross compiler.
(That's expensive in dollars...)

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Thu, 26 Jul 2001 21:57:07 GMT
Raw View
Pete Becker <petebecker@acm.org> writes:

| Howard Hinnant wrote:
| >
| > Personally I think that given that the C++ template system is a fully
| > functional compile time computation mechanism, it is a shame that
| > compile time floating point computation (which is generally done
| > anyway) is excluded.
| >
|
| C doesn't support floating point math in the preprocessor because that
| would require compile-time emulation of floating point math for the
| target system, which could be very expensive for a cross compiler.

Even then how, in Standardese, could one tell the program translator
to use this or that rounding mode?

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Thu, 26 Jul 2001 22:55:42 GMT
Raw View
On Thu, 26 Jul 2001 19:55:35 GMT, Pete Becker <petebecker@acm.org> wrote:
> Howard Hinnant wrote:
> > In article <3B601115.A592E13F@acm.org>, Pete Becker <petebecker@acm.org> wrote:
> > | Howard Hinnant wrote:
> > | >
> > | > Can't the same argument be made against integral types?
> > |
> > | The difference is that with integral types you can test at compile
> > time | whether the values are the same.
> >
> > Actually I can do this with my current system.  I'm not a language
> > lawyer so I may be depending on an extension to the language without
> > realizing it.
>
> It's not technically an extension. Under the as-if rule the compiler is
> permitted to fold floating point arithmetic operations. But it's not
> required to, so that's definitely not portable.

Does that mean that a compiler that chooses to not perform
floating-point computations at compile time is required to perform
template instantiation at run-time?
Given the choice, I'd say the latter is much harder to do in general
than the former.

-- Niklas Matthies
--
The meeting of two personalities is like the contact of two chemical
substances. If there is any reaction, both are transformed.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Matthew Austern <austern@research.att.com>
Date: Thu, 26 Jul 2001 23:39:02 GMT
Raw View
Howard Hinnant <hinnant@antispam.twcny.rr.com> writes:

> Actually I can do this with my current system.  I'm not a language
> lawyer so I may be depending on an extension to the language without
> realizing it.
>
> #include <iostream>
>
> template <int I>
> struct int2type  // *
> {
>    static int const value = I;
> };
>
> int main()
> {
>    std::cout << int2type<1.0 == 1.000000001>::value << '\n';
>    std::cout << int2type<1.0 == 1.0000000000000000001>::value << '\n';
> }

I think you are depending on an extension, yes.  14.3.2, paragraph
1, is a complete list of the things you can pass as non-type
template arguments.  The only one that could possibly fit in this
case is the first bullet item: "an integral constant-expression of
integral or enumeration type".

Integral constant expressions are defined in 5.19, paragraph 1.
If I'm reading that paragraph correctly, then the expression
"1.0 == 1.000000001" does not qualify as an integral constant-
expression.

Here's the relevant quote.  Note especially the second sentence:

   An integral constant-expression can involve only
   literals, enumerators, const variables or static data
   members of integral or enumeration types initialized with
   constant expression, non-type template parameters of
   integral or enumeration types, and sizeof expressions
   expressions.  Floating literals can appear only if they
   are cast to integral or enumeration types.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Fri, 27 Jul 2001 01:06:51 GMT
Raw View
Niklas Matthies wrote:
>
> On Thu, 26 Jul 2001 19:55:35 GMT, Pete Becker <petebecker@acm.org> wrote:
> > Howard Hinnant wrote:
> > > In article <3B601115.A592E13F@acm.org>, Pete Becker <petebecker@acm.org> wrote:
> > > | Howard Hinnant wrote:
> > > | >
> > > | > Can't the same argument be made against integral types?
> > > |
> > > | The difference is that with integral types you can test at compile
> > > time | whether the values are the same.
> > >
> > > Actually I can do this with my current system.  I'm not a language
> > > lawyer so I may be depending on an extension to the language without
> > > realizing it.
> >
> > It's not technically an extension. Under the as-if rule the compiler is
> > permitted to fold floating point arithmetic operations. But it's not
> > required to, so that's definitely not portable.
>
> Does that mean that a compiler that chooses to not perform
> floating-point computations at compile time is required to perform
> template instantiation at run-time?

No, it's the reason that floating point values aren't allowed as
template non-type arguments.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]