std::max(unsigned, size_t), amd64 and C++0x

This is a discussion on std::max(unsigned, size_t), amd64 and C++0x within the c++ forums in Programming Languages category; Hi, This definitely should have been asked before, but now I just cannot seem to find the related topic. unsigned i = 1; size_t j = 2; std::cout << std::max(i, j); This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau online), but fails to compile on amd64 platform. g++ reports: error: no matching function for call to ‘max(unsigned int&, size_t&)’ The problem, I believe, is that std::max is declared like template< typename T > T max(T a, T b) { ... } and that `unsigned' and `size_t' are actually different types with g++ on amd64, but ...

Go Back   Application Development Forum > Programming Languages > c++

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-27-2008, 02:04 AM
Alex Shulgin
Guest
 
Default std::max(unsigned, size_t), amd64 and C++0x

Hi,

This definitely should have been asked before, but now I just cannot
seem to find the related topic.

unsigned i = 1;
size_t j = 2;
std::cout << std::max(i, j);

This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau
online), but fails to compile on amd64 platform. g++ reports:

error: no matching function for call to ‘max(unsigned int&, size_t&)’

The problem, I believe, is that std::max is declared like

template< typename T > T max(T a, T b) { ... }

and that `unsigned' and `size_t' are actually different types with g++
on amd64, but are the same on i386.

In order to support different arbitrary types in std::max() arguments
we would need some magic template like this:

template< typename T, typename U >
typename wider_type< T, U >::type max(T t, U u) { ... }

and this is barely possible w/o writing down by hand all the needed
specializations for wider_type<>.

To me this is a reminiscent of some classical problem with C++
templates I cannot recall correctly now...

Is C++0x's `auto' supposed to handle this sort of things?

--
Cheers,
Alex Shulgin


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

Reply With Quote
  #2  
Old 08-28-2008, 04:14 AM
Nick Hounsome
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

On 27 Aug, 07:04, Alex Shulgin <alex.shul...@gmail.com> wrote:
> Hi,
>
> This definitely should have been asked before, but now I just cannot
> seem to find the related topic.
>
> unsigned i = 1;
> size_t j = 2;
> std::cout << std::max(i, j);
>
> This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau
> online), but fails to compile on amd64 platform. g++ reports:
>
> error: no matching function for call to ‘max(unsigned int&, size_t&)’
>
> The problem, I believe, is that std::max is declared like
>
> template< typename T > T max(T a, T b) { ... }
>
> and that `unsigned' and `size_t' are actually different types with g++
> on amd64, but are the same on i386.
>
> In order to support different arbitrary types in std::max() arguments
> we would need some magic template like this:
>
> template< typename T, typename U >
> typename wider_type< T, U >::type max(T t, U u) { ... }
>
> and this is barely possible w/o writing down by hand all the needed
> specializations for wider_type<>.
>
> To me this is a reminiscent of some classical problem with C++
> templates I cannot recall correctly now...
>
> Is C++0x's `auto' supposed to handle this sort of things?
>
> --
> Cheers,
> Alex Shulgin
>


Firstly auto wont do anything at all for this. decltype would be more
use since it would allow you to make j the same type as i.

Secondly I read somewhere recently a rant about the STL implementation
of max and why it was so complicated - It appears that for such an
intuitively simple function, max is actually extremely difficult, if
not impossible to get right in all cases.

Thirdly IMHO size_t should have been made a distinct type like wchar_t
because:
1) You could then overload on it.
2) You wouldn't get this sort of error message on some platforms and
not others - it would be an error everywhere.

And finally the solution is to make i a size_t or static cast it to
size_t in the call since size_t is never going to be smaller than
unsigned int.


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

Reply With Quote
  #3  
Old 08-28-2008, 04:20 AM
Marco Manfredini
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

Alex Shulgin wrote:

> unsigned i = 1;
> size_t j = 2;
> std::cout << std::max(i, j);
>
> This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau
> online), but fails to compile on amd64 platform. g++ reports:
>
> error: no matching function for call to ?max(unsigned int&, size_t&)?
>
> The problem, I believe, is that std::max is declared like
>
> template< typename T > T max(T a, T b) { ... }


It's more like the problem that max is declared:
template< typename T > const T& max(const T& a, const T &b) { ... }

Which makes the wider_type<> attempt somewhat infeasible.


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

Reply With Quote
  #4  
Old 08-28-2008, 04:21 AM
peter koch larsen
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

On 27 Aug., 08:04, Alex Shulgin <alex.shul...@gmail.com> wrote:
> Hi,
>
> This definitely should have been asked before, but now I just cannot
> seem to find the related topic.
>
> unsigned i = 1;
> size_t j = 2;
> std::cout << std::max(i, j);
>
> This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau
> online), but fails to compile on amd64 platform. g++ reports:
>
> error: no matching function for call to ‘max(unsigned int&, size_t&)’
>
> The problem, I believe, is that std::max is declared like
>
> template< typename T > T max(T a, T b) { ... }
>
> and that `unsigned' and `size_t' are actually different types with g++
> on amd64, but are the same on i386.


Right. So this is not really a problem with the std::max template, but
rather with your code that mixes up two different types. Correct the
problem by having a consistent use of types.
>
> In order to support different arbitrary types in std::max() arguments
> we would need some magic template like this:
>
> template< typename T, typename U >
> typename wider_type< T, U >::type max(T t, U u) { ... }
>
> and this is barely possible w/o writing down by hand all the needed
> specializations for wider_type<>.


I have seen "better" definitions of max, but they are rather complex
and IMHO not worth the trouble. Normally the arguments to std::max
should have the same type, and in the rare case where they do not, it
is better to explicitly qualify max as in e.g. std::max<size_t>(a,b).

/Peter


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

Reply With Quote
  #5  
Old 08-28-2008, 04:58 AM
Alberto Ganesh Barbati
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

Alex Shulgin ha scritto:
> Hi,
>
> This definitely should have been asked before, but now I just cannot
> seem to find the related topic.
>
> unsigned i = 1;
> size_t j = 2;
> std::cout << std::max(i, j);
>
> This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau
> online), but fails to compile on amd64 platform. g++ reports:
>
> error: no matching function for call to ‘max(unsigned int&, size_t&)’
>
> The problem, I believe, is that std::max is declared like
>
> template< typename T > T max(T a, T b) { ... }
>
> and that `unsigned' and `size_t' are actually different types with g++
> on amd64, but are the same on i386.
>
> In order to support different arbitrary types in std::max() arguments
> we would need some magic template like this:
>
> template< typename T, typename U >
> typename wider_type< T, U >::type max(T t, U u) { ... }
>
> and this is barely possible w/o writing down by hand all the needed
> specializations for wider_type<>.


This should be a job for the new common_type<> template introduced in
the latest draft of C++0x. Alas, the current wording of common_type<>
would produce the wrong result in the mixed-sign case max(-1, 1u). This
is my first and strongest objection to the current wording of
common_type<> but my alternative proposal received a very cold feedback.

> To me this is a reminiscent of some classical problem with C++
> templates I cannot recall correctly now...


Actually, this is a safety feature...

> Is C++0x's `auto' supposed to handle this sort of things?


Unfortunately, no: auto won't help in this case.

Ganesh


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

Reply With Quote
  #6  
Old 08-28-2008, 04:32 PM
Erik Wikström
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

On 2008-08-27 08:04, Alex Shulgin wrote:
> Hi,
>
> This definitely should have been asked before, but now I just cannot
> seem to find the related topic.
>
> unsigned i = 1;
> size_t j = 2;
> std::cout << std::max(i, j);
>
> This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau
> online), but fails to compile on amd64 platform. g++ reports:
>
> error: no matching function for call to ‘max(unsigned int&, size_t&)’
>
> The problem, I believe, is that std::max is declared like
>
> template< typename T > T max(T a, T b) { ... }
>
> and that `unsigned' and `size_t' are actually different types with g++
> on amd64, but are the same on i386.
>
> In order to support different arbitrary types in std::max() arguments
> we would need some magic template like this:
>
> template< typename T, typename U >
> typename wider_type< T, U >::type max(T t, U u) { ... }
>
> and this is barely possible w/o writing down by hand all the needed
> specializations for wider_type<>.
>
> To me this is a reminiscent of some classical problem with C++
> templates I cannot recall correctly now...
>
> Is C++0x's `auto' supposed to handle this sort of things?


No, auto will only save you from typing the whole typename when it can
be deducted from the expression (in this case from the function
declaration). What might help in this case is decltype.

--
Erik Wikström


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

Reply With Quote
  #7  
Old 08-28-2008, 04:35 PM
gpderetta
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

On Aug 27, 8:04 am, Alex Shulgin <alex.shul...@gmail.com> wrote:
> Hi,
>
> This definitely should have been asked before, but now I just cannot
> seem to find the related topic.
>
> unsigned i = 1;
> size_t j = 2;
> std::cout << std::max(i, j);
>
> This code compiles w/o a problem on i386 (tried g++ 4.1.2 and Comeau
> online), but fails to compile on amd64 platform. g++ reports:
>
> error: no matching function for call to ‘max(unsigned int&, size_t&)’
>
> The problem, I believe, is that std::max is declared like
>
> template< typename T > T max(T a, T b) { ... }
>
> and that `unsigned' and `size_t' are actually different types with g++
> on amd64, but are the same on i386.
>


An easy solution is to explicitly name the template parameter:

max<size_t>(i,j)

<snip>
> Is C++0x's `auto' supposed to handle this sort of things?
>


I do not think it will help.

Min/max definition will likely change in C++0x, but I do not remember
if this case is handled diferently.

HTH,

--
gpd


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

Reply With Quote
  #8  
Old 08-28-2008, 04:52 PM
Panhinda
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

> unsigned i = 1;
> size_t j = 2;
> std::cout << std::max(i, j);


The prototype says both parameters must be of same type. This code
violates the prototype - hence the compile error. You should do
something along the lines of -

unsigned i = 1;
size_t j = 2;
std::cout << std::max<size_t>(i, static_cast<size_t>(i));

This will compile on any platform.



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

Reply With Quote
  #9  
Old 08-28-2008, 05:58 PM
Pete Becker
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

On 2008-08-27 22:58:40 -0400, Alberto Ganesh Barbati
<AlbertoBarbati@libero.it> said:

>
> This should be a job for the new common_type<> template introduced in
> the latest draft of C++0x. Alas, the current wording of common_type<>
> would produce the wrong result in the mixed-sign case max(-1, 1u). This
> is my first and strongest objection to the current wording of
> common_type<> but my alternative proposal received a very cold feedback.


That is, it would be a job for the new common_type template if it did
what people expect it to do. But in reality, common_type is an
implementation detail for the new time stuff, not a general purpose
template, and shouldn't be exposed in the standard. The previous
version of the time stuff described its requirements without
prescribing a particular implementataion, so it didn't run into the
problems that common_type has.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)



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

Reply With Quote
  #10  
Old 08-28-2008, 05:58 PM
Pete Becker
Guest
 
Default Re: std::max(unsigned, size_t), amd64 and C++0x

On 2008-08-27 22:14:08 -0400, Nick Hounsome
<nick.hounsome@googlemail.com> said:

>
> Secondly I read somewhere recently a rant about the STL implementation
> of max and why it was so complicated - It appears that for such an
> intuitively simple function, max is actually extremely difficult, if
> not impossible to get right in all cases.


The implementation of max is not complicated at all:

template <class T> T max(const T& t1, const T& t2) { return t1 < t2 ?
t2 : t2; }

Maybe you're thinking of a proposal to add a bunch of stuff to max that
bloated it to over 200 lines of code in order to "improve" it.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)



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

Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 02:53 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.