Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » C++Goto page 1, 2, 3, 4, 5, 6, 7, 8, 9  Next

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

 
Jump to:  
 
Alex Shulgin
PostPosted: Wed Aug 27, 2008 6:04 am    Post subject: 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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Nick Hounsome
PostPosted: Thu Aug 28, 2008 8:14 am    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
On 27 Aug, 07:04, Alex Shulgin <alex.shul...@gmail.com> wrote:
Quote:
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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Marco Manfredini
PostPosted: Thu Aug 28, 2008 8:20 am    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
Alex Shulgin wrote:

Quote:
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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
peter koch larsen
PostPosted: Thu Aug 28, 2008 8:21 am    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
On 27 Aug., 08:04, Alex Shulgin <alex.shul...@gmail.com> wrote:
Quote:
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.
Quote:

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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Alberto Ganesh Barbati
PostPosted: Thu Aug 28, 2008 8:58 am    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
Alex Shulgin ha scritto:
Quote:
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.

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

Actually, this is a safety feature...

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

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

Ganesh


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Erik Wikström
PostPosted: Thu Aug 28, 2008 8:32 pm    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
On 2008-08-27 08:04, Alex Shulgin wrote:
Quote:
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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
gpderetta
PostPosted: Thu Aug 28, 2008 8:35 pm    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
On Aug 27, 8:04 am, Alex Shulgin <alex.shul...@gmail.com> wrote:
Quote:
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>
Quote:
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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Panhinda
PostPosted: Thu Aug 28, 2008 8:52 pm    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
Quote:
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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
SG
PostPosted: Thu Aug 28, 2008 9:58 pm    Post subject: Re: std::max(unsigned, size_t), amd64 and C++0x
       
On 27 Aug., 08:04, Alex Shulgin <alex.shul...@gmail.com> wrote:
Quote:
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.

Implicit convertibility of types is not considered during template
parameter deduction. But you can help the compiler choose the "right"
template parameter:

unsigned a = get_a();
size_t b = get_b();
size_t max = std::max<size_t>(a,b);

Explicit conversion will also work:

size_t max = std::max(size_t(a),b);

Though, I'm not sure whether it's safe to assume that sizeof(unsigned)
<= sizeof(size_t). To be on the safe side you may want to use some
metaprogramming tricks a la decltype(a+b) for the right type.

Cheers,
SG

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Pete Becker
PostPosted: Thu Aug 28, 2008 9:58 pm    Post subject: 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:

Quote:

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 LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Page 1 of 9 .:. Goto page 1, 2, 3, 4, 5, 6, 7, 8, 9  Next

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

UB 04 Ryanair vip service poland pop bet at home