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

Visual C++ 2019 is having a hissy fit over these two lines of code

48 views
Skip to first unread message

Lynn McGuire

unread,
Jul 19, 2023, 10:47:12 PM7/19/23
to
And Visual C++ 2019 is having a hissy fit over these two lines of code:

static const size_t size_t_max = std::numeric_limits<size_t>::max();
static const ssize_t ssize_t_max = std::numeric_limits<ssize_t>::max();

That code worked just fine in Visual C++ 2015. What am I screwing up here ?

Thanks,
Lynn

Lynn McGuire

unread,
Jul 19, 2023, 10:49:10 PM7/19/23
to
You know, I should give the error code:

Severity Code Description Project File Line Suppression State
Error C2440 'initializing': cannot convert from 'unsigned int (__cdecl
*)(void) noexcept' to 'fem::size_t' dii_c_library
C:\dii\inc\fem\size_t.hpp 12

And here is the file:

#ifndef FEM_SIZE_T_HPP
#define FEM_SIZE_T_HPP

#include <limits>
#include <cstddef>

namespace fem {

typedef std::size_t size_t;
typedef std::ptrdiff_t ssize_t;

static const size_t size_t_max = std::numeric_limits<size_t>::max();
static const ssize_t ssize_t_max = std::numeric_limits<ssize_t>::max();

template <typename T>
struct array_of_2
{
T elems[2];

array_of_2() {}

array_of_2(T const& i, T const& j) { elems[0] = i; elems[1] = j; }
};

typedef array_of_2<size_t> size_t_2;
typedef array_of_2<ssize_t> ssize_t_2;

} // namespace fem

#endif // GUARD

Thanks,
Lynn

Andrey Tarasevich

unread,
Jul 20, 2023, 12:47:08 AM7/20/23
to
On 07/19/23 7:48 PM, Lynn McGuire wrote:
> You know, I should give the error code:

Compiles perfectly fine in my VS2019.

The first thought was that it was just another example of the well-known
conflict with Windows' own min/max macros. But regardless of `NOMINMAX`
state, this code compiled without any issues for me.

--
Best regards,
Andrey

Lynn McGuire

unread,
Jul 20, 2023, 1:31:55 AM7/20/23
to
Thanks !

I can fix the problem by replacing the
std::numeric_limits<size_t>::max(); with UINT_MAX. But, that is a cheat.

Thanks,
Lynn


Keith Thompson

unread,
Jul 20, 2023, 1:52:08 AM7/20/23
to
Surely you mean SIZE_MAX, defined in <cstdint>. (It's common for int to
be 32 bits and size_t 64 bits.)

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

Alf P. Steinbach

unread,
Jul 20, 2023, 3:04:52 AM7/20/23
to
I can't see anything technically wrong and it compiles fine with current
Visual C++ and g++.

Not what you're asking but note that

* `typedef` is old C syntax, modern `using` can be more clear.
* `const` at namespace scope implies `static`, i.e. no need to repeat.
* `array_of_2` won't work for T that's not default constructible.

Here's re-styling of the code with the above 3 points addressed:

#pragma once
#include <limits> // std::numeric_limits
#include <utility> // std::move
#include <cstddef> // std::(size_t, ptrdiff_t)

namespace fem {
using std::numeric_limits,
std::move;

using size_t = std::size_t;
using ssize_t = std::ptrdiff_t;

template< class Type >
constexpr Type max_ = numeric_limits<Type>::max();

constexpr size_t size_t_max = max_<size_t>;
constexpr ssize_t ssize_t_max = max_<ssize_t>;

template< class T >
struct array_of_2_
{
T elems[2];

array_of_2_() {}
array_of_2_( T a, T b ): elems{ move( a ), move( b ) } {}
};

using size_t_2 = array_of_2_<size_t> ;
using ssize_t_2 = array_of_2_<ssize_t> ;
} // namespace fem

- Alf


Paavo Helde

unread,
Jul 20, 2023, 4:22:43 AM7/20/23
to
20.07.2023 05:48 Lynn McGuire kirjutas:
> On 7/19/2023 9:46 PM, Lynn McGuire wrote:
>> And Visual C++ 2019 is having a hissy fit over these two lines of code:
>>
>> static const size_t size_t_max = std::numeric_limits<size_t>::max();
>> static const ssize_t ssize_t_max = std::numeric_limits<ssize_t>::max();
>>
>> That code worked just fine in Visual C++ 2015.  What am I screwing up
>> here ?
>>
>> Thanks,
>> Lynn
>
> You know, I should give the error code:
>
> Severity    Code    Description    Project    File    Line
> Suppression State
> Error    C2440    'initializing': cannot convert from 'unsigned int
> (__cdecl *)(void) noexcept' to 'fem::size_t'    dii_c_library
> C:\dii\inc\fem\size_t.hpp    12


This complains about converting a function to an integer. The following
line would emit the same error:

static const size_t size_t_max = std::numeric_limits<size_t>::max;

Suspecting either you did not post the actual failing code, or there is
some evil macro hackery going on. To figure that out, hover the mouse
over 'max', or right-click on it and select 'go to definition'.

Malcolm McLean

unread,
Jul 20, 2023, 4:53:20 AM7/20/23
to
Try
static const size_t size_t_max = (std::numeric_limits<size_t>::max)();

Ralf Fassel

unread,
Jul 20, 2023, 9:20:17 AM7/20/23
to
* Lynn McGuire <lynnmc...@gmail.com>
| Severity Code Description Project File Line Suppression State
| Error C2440 'initializing': cannot convert from 'unsigned int (__cdecl
| *)(void) noexcept' to 'fem::size_t' dii_c_library
| C:\dii\inc\fem\size_t.hpp 12
>
| And here is the file:
>
| #ifndef FEM_SIZE_T_HPP
| #define FEM_SIZE_T_HPP
>
| #include <limits>
| #include <cstddef>
>
| namespace fem {
>
| typedef std::size_t size_t;
| typedef std::ptrdiff_t ssize_t;
>
| static const size_t size_t_max = std::numeric_limits<size_t>::max();
| static const ssize_t ssize_t_max = std::numeric_limits<ssize_t>::max();

Check whether

#undef max
static const size_t size_t_max = std::numeric_limits<size_t>::max();

makes a difference at that position. If so, it *is* the 'max' macro,
and it very much depends on other include files before the current one
whether this triggers or not.

HTH
R'

Bonita Montero

unread,
Jul 20, 2023, 10:11:19 AM7/20/23
to
For me is #define-ing NOMIMMAX before including <Windows.h>
the smarter solution.


Lynn McGuire

unread,
Jul 20, 2023, 3:05:39 PM7/20/23
to
I get the following "limits" code for min and max.

template <>
class numeric_limits<unsigned int> : public _Num_int_base {
public:
_NODISCARD static constexpr unsigned int(min)() noexcept {
return 0;
}

_NODISCARD static constexpr unsigned int(max)() noexcept {
return UINT_MAX;
}


Thanks,
Lynn

Lynn McGuire

unread,
Jul 20, 2023, 3:20:17 PM7/20/23
to
Nope, that threw me into std::max hell. Then I get an error on:

size_t n = std::max(lhs_size, rhs_size);

Thanks,
Lynn

Chris M. Thomasson

unread,
Jul 20, 2023, 3:58:16 PM7/20/23
to
Don't forget WIN32_LEAN_AND_MEAN ... :^)

Paavo Helde

unread,
Jul 20, 2023, 4:27:40 PM7/20/23
to
This still feels strongly like evil macro abuse. Try

#undef max

before the error points.

Paavo Helde

unread,
Jul 20, 2023, 4:33:02 PM7/20/23
to
This is the correct definition which ought to be used. Incidentally,
this shows MS is also protecting itself from evil macro hackery (mostly
caused by MS itself), by placing min and max in parens.

In general, if Visual Studio is acting weird, sometimes it might be
helpful to Rebuild All, and/or to even delete the .vs folder where it
caches a lot of things.





Bonita Montero

unread,
Jul 20, 2023, 10:52:03 PM7/20/23
to
That's 100ms difference when compiling for me (7950X).

Pavel

unread,
Jul 20, 2023, 11:20:48 PM7/20/23
to
Any code is written to be read by humans. Uniform hurts the readability,
specific improves it. Plus, using declaration make the reader read more
tokens. Upshot: use typedef where you can and using where you can't.

> * `const` at namespace scope implies `static`, i.e. no need to repeat.
Another change from more to less readable code. In order to know a
declaration is in a namespace, one has to either keep this in mind or
look up. The former is inefficient in space, the latter -- in time.
Upshot: feel free to be helpful and use static.

Morale: a new shiny multitool is not a universally good replacement for
the old good pliers.

> * `array_of_2` won't work for T that's not default constructible.
>
> Here's re-styling of the code with the above 3 points addressed:
>
>     #pragma once
>     #include <limits>       // std::numeric_limits
>     #include <utility>      // std::move
>     #include <cstddef>      // std::(size_t, ptrdiff_t)
>
>     namespace fem {
>         using   std::numeric_limits,
>                 std::move;
>
>         using size_t    = std::size_t;
>         using ssize_t   = std::ptrdiff_t;
>
>         template< class Type >
>         constexpr Type max_ = numeric_limits<Type>::max();
>
>         constexpr size_t  size_t_max  = max_<size_t>;
>         constexpr ssize_t ssize_t_max = max_<ssize_t>;
>
>         template< class T >
>         struct array_of_2_
>         {
>             T elems[2];
>
>             array_of_2_() {}
>             array_of_2_( T a, T b ): elems{ move( a ), move( b ) } {}
>         };
>
>         using size_t_2    = array_of_2_<size_t> ;
>         using ssize_t_2   = array_of_2_<ssize_t> ;
>     } // namespace fem
>
> - Alf
>
>

Cheers,
-Pavel

Chris M. Thomasson

unread,
Jul 21, 2023, 3:59:20 PM7/21/23
to
:^) Still, its something that was ingrained in my brain from long ago.
0 new messages