Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

1.0 / 0.0

111 views
Skip to first unread message

Bonita Montero

unread,
Dec 29, 2021, 2:00:21 PM12/29/21
to
I just wanted to give a set a load-factor of +Inf. So I just wrote
1.0f / 0.0f to prevent numeric_limits<float>::infinity() because
the first is shorter. MSVC took this as an error but clang++ and
clang-cl accepted the code. Which compiler is right ?

Jack Lemmon

unread,
Dec 29, 2021, 2:18:10 PM12/29/21
to
In mathematics, a number divided by zero is undefined. So I would say
MSVC is correct though it should have simply said <Nan>.


Bonita Montero

unread,
Dec 29, 2021, 3:20:26 PM12/29/21
to
No, it's infinity. 0.0 / 0.0 is NaN.

james...@alumni.caltech.edu

unread,
Dec 29, 2021, 4:09:09 PM12/29/21
to
Both are right. "If the second operand of / or % is zero the behavior
is undefined." (7.6.5p4). When the behavior is undefined, there's
no wrong way to handle it. In particular, it's permitted to implement
ISO/IEC 60559 (== IEEE 754) semantics. I won't be able to check
my copy of that standard until Monday, but off the top of my head,
I think it specifies that division by 0 results in an infinity with the
same sign as the numerator.

daniel...@gmail.com

unread,
Dec 29, 2021, 11:38:03 PM12/29/21
to
On Wednesday, December 29, 2021 at 4:09:09 PM UTC-5, james...@alumni.caltech.edu wrote:
> On Wednesday, December 29, 2021 at 2:00:21 PM UTC-5, Bonita Montero wrote:
> > So I just wrote
> > 1.0f / 0.0f ... MSVC took this as an error but clang++ and
> > clang-cl accepted the code. Which compiler is right ?
> Both are right. "If the second operand of / or % is zero the behavior
> is undefined." (7.6.5p4). When the behavior is undefined, there's
> no wrong way to handle it. In particular, it's permitted to implement
> ISO/IEC 60559 (== IEEE 754) semantics. I won't be able to check
> my copy of that standard until Monday, but off the top of my head,
> I think it specifies that division by 0 results in an infinity with the
> same sign as the numerator.

It does.

I believe for all of these compilers, on popular OS's including Ubuntu,
Windows 10, MacOS,

std::numeric_limits<double>::is_iec559

returns true by default, which means they should support IEEE 754 standard.
Microsoft vs returns true on Windows, but errors on 1.0/0. So I think
vs is wrong.

Daniel


Paavo Helde

unread,
Dec 30, 2021, 10:25:42 AM12/30/21
to
Not sure which one is right, but here is a workaround;-) It's shorter
than std::numeric_limits<float>::infinity(), isn't it?

float x = 1.f/[](){return 0.f;}();

daniel...@gmail.com

unread,
Dec 30, 2021, 11:55:44 AM12/30/21
to
Yes, but I think that's division by a non constant expression. Surprisingly
(to me), this (still shorter!)

float x = 1.f/[]() constexpr {return 0.f;}();

also works with MSVC C++ 17 and greater, but

constexpr float zero = 0;
float x = 1.f / 1.f / zero;

does not (compile time error, "div or mod by zero".)

Daniel


Manfred

unread,
Dec 30, 2021, 12:48:26 PM12/30/21
to
If all you want is a compact expression, why not HUGE_VAL, HUGE_VALF,
HUGE_VALL from <cmath> (aka <math.h>)?

These are standardized by reference from C, and guaranteed to work.
1.0f/0.0f is just an unportable hack.

daniel...@gmail.com

unread,
Dec 30, 2021, 1:17:01 PM12/30/21
to
On Thursday, December 30, 2021 at 12:48:26 PM UTC-5, Manfred wrote:
> If all you want is a compact expression, why not HUGE_VAL, HUGE_VALF,
> HUGE_VALL from <cmath> (aka <math.h>)?
>

Why not INFINITY from math.h?

Manfred

unread,
Dec 30, 2021, 2:02:37 PM12/30/21
to
Also possible, yes.
BTW the standard lists it both under <float.h> and <math.h>

Mut...@dastardlyhq.com

unread,
Dec 31, 2021, 5:25:48 AM12/31/21
to
On Thu, 30 Dec 2021 20:02:21 +0100
Manfred <non...@add.invalid> wrote:
>On 12/30/2021 7:16 PM, daniel...@gmail.com wrote:
>> On Thursday, December 30, 2021 at 12:48:26 PM UTC-5, Manfred wrote:
>>> If all you want is a compact expression, why not HUGE_VAL, HUGE_VALF,
>>> HUGE_VALL from <cmath> (aka <math.h>)?
>>>
>>
>> Why not INFINITY from math.h?
>>
>
>Also possible, yes.

Certainly all better than some ugly divide by zero hack.

Manfred

unread,
Dec 31, 2021, 12:35:13 PM12/31/21
to
And obviously, if you really want it C++ish

namespace my
{
static constexpr float inf = std::numeric_limits<float>::infinity();
}

/* use my::inf wherever you like */

Juha Nieminen

unread,
Jan 3, 2022, 1:22:11 AM1/3/22
to
Manfred <non...@add.invalid> wrote:
> namespace my
> {
> static constexpr float inf = std::numeric_limits<float>::infinity();
> }

I don't think a constexpr variable needs to be 'static'.

red floyd

unread,
Jan 3, 2022, 3:12:02 AM1/3/22
to
Yeah, don't they have internal linkage by default, like const does?

Alf P. Steinbach

unread,
Jan 3, 2022, 3:28:42 AM1/3/22
to
Yes, `constexpr` implies (drags in) `inline` and `const`.

Still, in a class definition `static` means something else than above,
and can't be omitted for a `constexpr` data member.

That's unreasonable to me: the language /requiring/ you to write a
meaningless filler word, a word that can't be omitted but carries no
extra meaning and doesn't help the compiler's parsing. As I see it
`constexpr` for data should also have implied static storage duration.
It's gut-wrenching that it does not.

- Alf

Juha Nieminen

unread,
Jan 3, 2022, 3:36:48 AM1/3/22
to
Alf P. Steinbach <alf.p.s...@gmail.com> wrote:
> Still, in a class definition `static` means something else than above,
> and can't be omitted for a `constexpr` data member.
>
> That's unreasonable to me: the language /requiring/ you to write a
> meaningless filler word, a word that can't be omitted but carries no
> extra meaning and doesn't help the compiler's parsing. As I see it
> `constexpr` for data should also have implied static storage duration.
> It's gut-wrenching that it does not.

I haven't tried it, but couldn't a (non-static) constexpr member
variable be usable in classes that are intended for constexpr
evaluation only?

Or is it semantically just not possible to have a non-static
constexpr member variable?

Mut...@dastardlyhq.com

unread,
Jan 3, 2022, 4:25:16 AM1/3/22
to
On Mon, 3 Jan 2022 09:28:25 +0100
"Alf P. Steinbach" <alf.p.s...@gmail.com> wrote:
>On 3 Jan 2022 09:11, red floyd wrote:
>> On 1/2/2022 10:21 PM, Juha Nieminen wrote:
>>> Manfred <non...@add.invalid> wrote:
>>>> namespace my
>>>> {
>>>>    static constexpr float inf = std::numeric_limits<float>::infinity();
>>>> }
>>>
>>> I don't think a constexpr variable needs to be 'static'.
>>
>> Yeah, don't they have internal linkage by default, like const does?
>
>Yes, `constexpr` implies (drags in) `inline` and `const`.
>
>Still, in a class definition `static` means something else than above,
>and can't be omitted for a `constexpr` data member.
>
>That's unreasonable to me: the language /requiring/ you to write a
>meaningless filler word, a word that can't be omitted but carries no
>extra meaning and doesn't help the compiler's parsing. As I see it

In a similar vein, why does C++ still insist on class static values being set
outside of the class? eg:

struct myclass
{
static int i;
};

int myclass::i = 123;

Why on earth can't I just do:

struct myclass
{
static int i = 123;
};

in the same way that const members are initialised? I've never seen a good
reason why it must be this way and it makes for messy header files.


David Brown

unread,
Jan 3, 2022, 11:15:08 AM1/3/22
to
struct myclass
{
inline static int i = 123;
};

This has been valid since C++17, along with inline variables. (Why do
you need "inline" here? Good question, and I hope someone else can
geive a good answer!)

<https://en.cppreference.com/w/cpp/language/static#Static_data_members>

Mut...@dastardlyhq.com

unread,
Jan 3, 2022, 11:23:10 AM1/3/22
to
Thanks for that, didn't know. Hope the inline doesn't throw up wierd
optimisation issues. Why its taken over 3 decades to do this simple obvious
change when they've been busy throwing in a lot of syntatic nonsense no one
asked for (user literals being the best example IMO) instead is also a good
question.

Scott Lurndal

unread,
Jan 3, 2022, 12:40:44 PM1/3/22
to
>give a good answer!)

Probably for backward compatability. Note that historically C++ was
translated to C then compiled (e.g. cfront). Trying to do the static
initialization in the class definition would result in linker errors
due to duplicate definitions of the static variable when the class
definition is include by multiple compilation units. Hence the requirement
to declare it in a single compilation unit.

Manfred

unread,
Jan 3, 2022, 5:15:10 PM1/3/22
to
That's true, but I still like to be explicit, since 'static' and 'const'
mean different things.

The irony is that this is probably one of those examples where C beats
C++ - good ol' HUGE_VALF or INFINITE would raise no question at all!

Öö Tiib

unread,
Jan 4, 2022, 2:50:20 AM1/4/22
to
The std::numeric_limits<float>::infinity() does not raise questions
in actual programs either. It is infinity of float, very explicitly.
Issues of BM with it are pseudo-issues. Too lot of characters?
WTF? Did the hard drive get full? Name some local constant
like "beyond_horizon" or something. Next BM needs to output it to
json as number and then what? Runs away crying?

Juha Nieminen

unread,
Jan 4, 2022, 2:58:59 AM1/4/22
to
Mut...@dastardlyhq.com wrote:
> In a similar vein, why does C++ still insist on class static values being set
> outside of the class? eg:
>
> struct myclass
> {
> static int i;
> };
>
> int myclass::i = 123;
>
> Why on earth can't I just do:
>
> struct myclass
> {
> static int i = 123;
> };

As you probably know, 'static' variables declared inside a class aren't
actually member variables, but free-floating variables which visibility
scope is inside that class (the term "class variable" is often used for
these types of variables, in many OO languages, as opposed to "member
variable").

The 'static int i;' in the class definition is just a declaration, and
it needs to be actually defined, ie. instantiated somewhere, in one
(and only one) compilation unit. If you don't instantiate it somewhere
the compiler will be unable to decide where to instantiate it and you'll
get a linker error because it has only been declared but not instantiated
in any compilation unit.

C++17 extended the 'inline' functionality, which does that automatically
for you (so that you don't have to instantiate the variable by hand),
but prior to it you had to do it yourself.

I suppose that when C++98 was standardized it was decided that it's
better to specify the initial value of that 'static' variable where
it's instantiated rather than where it's declared. (I suppose that
technically speaking it wouldn't be hard for compilers to look up
the initial value from either one, because to instantiate the variable
it needs to see the declaration.) Perhaps it was thought that it causes
less confusion because if it's initialized in the declaration it may
look like it will be initialized to that value every time the class
is instantiated (which, of course, is not the case).

> in the same way that const members are initialised? I've never seen a good
> reason why it must be this way and it makes for messy header files.

I don't think const member variables can be initialized in the class
definition in C++98. That syntax was only introduced in C++11.

Juha Nieminen

unread,
Jan 4, 2022, 3:34:38 AM1/4/22
to
Manfred <non...@add.invalid> wrote:
> The irony is that this is probably one of those examples where C beats
> C++ - good ol' HUGE_VALF or INFINITE would raise no question at all!

What is the type of INFINITE? What if you want it as one of the other two
floating point types? (Is casting defined in this case?)

Mut...@dastardlyhq.com

unread,
Jan 4, 2022, 4:15:29 AM1/4/22
to
C++ hasn't been translated into C for 25 years at least. Keeping this syntatic
quirk for so long rather demonstrates the C++ committee are more interested in
adding shiny shiny "fun" stuff to the language that they find interesting
rather than improving it for normal developers.

Mut...@dastardlyhq.com

unread,
Jan 4, 2022, 4:17:36 AM1/4/22
to
I'd love to see their reasoning for that.

>technically speaking it wouldn't be hard for compilers to look up

It wouldn't be hard at all.

>the initial value from either one, because to instantiate the variable
>it needs to see the declaration.) Perhaps it was thought that it causes
>less confusion because if it's initialized in the declaration it may
>look like it will be initialized to that value every time the class
>is instantiated (which, of course, is not the case).

If someone was new to C++ perhaps, otherwise no.

>I don't think const member variables can be initialized in the class
>definition in C++98. That syntax was only introduced in C++11.

Quite possibly.

Manfred

unread,
Jan 4, 2022, 4:43:12 AM1/4/22
to
On 1/4/2022 8:50 AM, Öö Tiib wrote:
> On Tuesday, 4 January 2022 at 00:15:10 UTC+2, Manfred wrote:
>> On 1/3/2022 9:11 AM, red floyd wrote:
>>> On 1/2/2022 10:21 PM, Juha Nieminen wrote:
>>>> Manfred <non...@add.invalid> wrote:
>>>>> namespace my
>>>>> {
>>>>> static constexpr float inf = std::numeric_limits<float>::infinity();
>>>>> }
>>>>
>>>> I don't think a constexpr variable needs to be 'static'.
>>>
>>> Yeah, don't they have internal linkage by default, like const does?
>> That's true, but I still like to be explicit, since 'static' and 'const'
>> mean different things.
>>
>> The irony is that this is probably one of those examples where C beats
>> C++ - good ol' HUGE_VALF or INFINITE would raise no question at all!
>
> The std::numeric_limits<float>::infinity() does not raise questions
> in actual programs either. It is infinity of float, very explicitly.
No, I'm talking about these questions about 'static', 'const',
'constexpr' and similar entertainment. In C INFINITE and HUGE_VAL are
"constant expressions", and that is it - good for any purpose.

Manfred

unread,
Jan 4, 2022, 4:47:17 AM1/4/22
to
"The macro INFINITY expands to a constant expression of type float
representing positive or unsigned infinity"
It can't be any clearer than that.
I believe there are automatic conversions to double and long double.
Others can confirm and give the exact reference for this part.

HUGE_VAL comes in all variants for different types, from float to double
to decimal.

Scott Lurndal

unread,
Jan 4, 2022, 10:24:22 AM1/4/22
to
Of course, they did "fix" it - in a backward compatible way - in C++17, right?

Mut...@dastardlyhq.com

unread,
Jan 4, 2022, 11:06:46 AM1/4/22
to
On Tue, 04 Jan 2022 15:24:06 GMT
How exactly do you have backwards compatible new syntax?

And waiting until 2017 to (sort of) fix a rather basic syntatic fault doesn't
exactly suggest they have their finger on the pulse of C++ devs. But we knew
that anyway.

Öö Tiib

unread,
Jan 4, 2022, 1:16:03 PM1/4/22
to
On Tuesday, 4 January 2022 at 11:43:12 UTC+2, Manfred wrote:
> On 1/4/2022 8:50 AM, Öö Tiib wrote:
> > On Tuesday, 4 January 2022 at 00:15:10 UTC+2, Manfred wrote:
> >> On 1/3/2022 9:11 AM, red floyd wrote:
> >>> On 1/2/2022 10:21 PM, Juha Nieminen wrote:
> >>>> Manfred <non...@add.invalid> wrote:
> >>>>> namespace my
> >>>>> {
> >>>>> static constexpr float inf = std::numeric_limits<float>::infinity();
> >>>>> }
> >>>>
> >>>> I don't think a constexpr variable needs to be 'static'.
> >>>
> >>> Yeah, don't they have internal linkage by default, like const does?
> >> That's true, but I still like to be explicit, since 'static' and 'const'
> >> mean different things.
> >>
> >> The irony is that this is probably one of those examples where C beats
> >> C++ - good ol' HUGE_VALF or INFINITE would raise no question at all!
> >
> > The std::numeric_limits<float>::infinity() does not raise questions
> > in actual programs either. It is infinity of float, very explicitly.
> No, I'm talking about these questions about 'static', 'const',
> 'constexpr' and similar entertainment. In C INFINITE and HUGE_VAL are
> "constant expressions", and that is it - good for any purpose.

Then I'm lost ... std::numeric_limits<float>::infinity() IS constant expression
and that is it, good for any purpose.

Manfred

unread,
Jan 4, 2022, 2:49:47 PM1/4/22
to
On 1/4/22 7:15 PM, Öö Tiib wrote:
> On Tuesday, 4 January 2022 at 11:43:12 UTC+2, Manfred wrote:
>> On 1/4/2022 8:50 AM, Öö Tiib wrote:
>>> On Tuesday, 4 January 2022 at 00:15:10 UTC+2, Manfred wrote:
>>>> On 1/3/2022 9:11 AM, red floyd wrote:
>>>>> On 1/2/2022 10:21 PM, Juha Nieminen wrote:
>>>>>> Manfred <non...@add.invalid> wrote:
>>>>>>> namespace my
>>>>>>> {
>>>>>>> static constexpr float inf = std::numeric_limits<float>::infinity();
>>>>>>> }
>>>>>>
>>>>>> I don't think a constexpr variable needs to be 'static'.
>>>>>
>>>>> Yeah, don't they have internal linkage by default, like const does?
>>>> That's true, but I still like to be explicit, since 'static' and 'const'
>>>> mean different things.
>>>>
>>>> The irony is that this is probably one of those examples where C beats
>>>> C++ - good ol' HUGE_VALF or INFINITE would raise no question at all!
>>>
>>> The std::numeric_limits<float>::infinity() does not raise questions
>>> in actual programs either. It is infinity of float, very explicitly.
>> No, I'm talking about these questions about 'static', 'const',
>> 'constexpr' and similar entertainment. In C INFINITE and HUGE_VAL are
>> "constant expressions", and that is it - good for any purpose.
>
> Then I'm lost ... std::numeric_limits<float>::infinity() IS constant expression
> and that is it, good for any purpose.

I'll try and lend you a compass:

Manfred wrote:
> And obviously, if you really want it C++ish
>
> namespace my
> {
> static constexpr float inf = std::numeric_limits<float>::infinity();
> }
>
> /* use my::inf wherever you like */

The reason for it was to try and please C++ purists (we're in c.l.c++
after all), and get a compact representation of INF - I can see the
issue with using std::numeric_limits<float>::infinity() embedded in some
application expression, which serves totally different purposes than
inspecting the details of numeric representation of the implementation.

So, suppose you want compact, but you don't like <math.h>, the above is
an answer - note that obviously you want my::inf to be a constant
expression. Also, you want it local (as you say below), and along
similar lines I made it 'static', to make it clear - even if 'constexpr'
defaults to it.

BUT, then people started whirling around the use of 'static' in
combination with 'const' and 'constexpr' and all that fuzz - again, good
ol' C wouldn't do that - you'd just use INFINITY or one of the HUGE_VAL
variants, and be done with it.

Öö Tiib

unread,
Jan 4, 2022, 6:40:56 PM1/4/22
to
Yes, and for such cases when the infinity is used to somehow encode
something else I would put it into constant's name (like "beyond_horizon" I
mentioned below), as INFINITY or HUGE_VAL would be as confusing.

> So, suppose you want compact, but you don't like <math.h>, the above is
> an answer - note that obviously you want my::inf to be a constant
> expression. Also, you want it local (as you say below), and along
> similar lines I made it 'static', to make it clear - even if 'constexpr'
> defaults to it.
>
> BUT, then people started whirling around the use of 'static' in
> combination with 'const' and 'constexpr' and all that fuzz - again, good
> ol' C wouldn't do that - you'd just use INFINITY or one of the HUGE_VAL
> variants, and be done with it.

That fuzz I don't understand. It is perfectly OK to write static
constexpr, or static const about data member ... maybe I've just
done it too lot over the years. :(

Tim Rentsch

unread,
Jan 16, 2022, 3:40:57 PM1/16/22
to
I haven't checked the C++ standard, but in C (assuming a suitable
infinite value is available) the macro INFINITY expands to a
constant expression of type float, with an infinite value. Any
value of type float must have corresponding values in type double
and long double, and converting a float value to double or long
double must produce the corresponding value in the target type.
(Converting includes but is not limited to cast operations.)
0 new messages