C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Premature Array-to-Pointer Decay

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Tomás
Guest





PostPosted: Sun May 14, 2006 9:21 pm    Post subject: Premature Array-to-Pointer Decay Reply with quote



I have a short code sample here, and I believe that it should compile
without warning or error, and that it should print:

SomeFunc1: Array
SomeFunc2: Array
SomeFunc3: Array

Here's the code:

#include <cstdlib>
#include <iostream>
using std::cout;

/* 1 */
void SomeFunc1( double* const p )
{
cout << "SomeFunc1: Pointer\n";
}

void SomeFunc1( double (&array)[67] )
{
cout << "SomeFunc1: Array\n";
}


/* 2 */
void SomeFunc2( double* const p )
{
cout << "SomeFunc2: Pointer\n";
}

template<unsigned long len>
void SomeFunc2( double (&array)[len] )
{
cout << "SomeFunc2: Array\n";
}


/* 3 */
template<class T>
void SomeFunc3( T* const p )
{
cout << "SomeFunc3: Pointer\n";
}

template<class T, unsigned long len>
void SomeFunc3( T (&array)[len] )
{
cout << "SomeFunc3: Array\n";
}


int main()
{
double array[67];

SomeFunc1(array);

SomeFunc2(array);

SomeFunc3(array);

std::system("PAUSE");
}


It won't compile for me with g++ -- I get an ambiguity error for the call
to SomeFunc1:

call of overloaded `SomeFunc1(double[67])' is ambiguous
candidates are: void SomeFunc1(double*)
void SomeFunc1(double (&)[67])


If I comment-out the call to SomeFunc1, then it compiles successfully
without error or warning, and prints:

SomeFunc2: Pointer
SomeFunc3: Array


I think the original unaltered code should work as I intended it to.


-Tomás

---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
kanze
Guest





PostPosted: Wed May 17, 2006 5:21 pm    Post subject: Re: Premature Array-to-Pointer Decay Reply with quote



"Tomás" wrote:
Quote:
I have a short code sample here, and I believe that it should
compile without warning or error, and that it should print:

SomeFunc1: Array
SomeFunc2: Array
SomeFunc3: Array

Here's the code:

#include <cstdlib
#include <iostream
using std::cout;

/* 1 */
void SomeFunc1( double* const p )
{
cout << "SomeFunc1: Pointer\n";
}

void SomeFunc1( double (&array)[67] )
{
cout << "SomeFunc1: Array\n";
}

I'm not sure, but I don't think that there is any way to call
the second without the call being ambiguous. If I read
§13.3.3.1.1 correctly, array to pointer conversions are
considered an exact match. (There are a number of special cases
in §13.3.3.2, but none of them seem to apply here.) If the
parameter type is "double [67]", the call is ambiguous, and in
all other cases (modulo const/volatile qualifiers), the first
function is called.

Quote:
/* 2 */
void SomeFunc2( double* const p )
{
cout << "SomeFunc2: Pointer\n";
}

template<unsigned long len
void SomeFunc2( double (&array)[len] )
{
cout << "SomeFunc2: Array\n";
}

A similar problem here: except that there is no ambiguity, since
non-template beats template as a tie breaker. The template
version will never be called, and there will never be an
ambiguity.

Quote:
/* 3 */
template<class T
void SomeFunc3( T* const p )
{
cout << "SomeFunc3: Pointer\n";
}

template<class T, unsigned long len
void SomeFunc3( T (&array)[len] )
{
cout << "SomeFunc3: Array\n";
}

This is the interesting case. IMHO, argument deduction should
succeed for both cases, and the resulting call should be
ambiguous, as in the first case.

Quote:
int main()
{
double array[67];

SomeFunc1(array);

SomeFunc2(array);

SomeFunc3(array);

std::system("PAUSE");
}

It won't compile for me with g++ -- I get an ambiguity error
for the call to SomeFunc1:

call of overloaded `SomeFunc1(double[67])' is ambiguous
candidates are: void SomeFunc1(double*)
void SomeFunc1(double (&)[67])

If I comment-out the call to SomeFunc1, then it compiles
successfully without error or warning, and prints:

SomeFunc2: Pointer
SomeFunc3: Array

I think the original unaltered code should work as I intended
it to.

I don't think so. My version of g++ (4.1.0) agrees with my
analysis above -- it finds both SomeFunc1 and SomeFunc3
ambiguous.

The problem isn't, as you suggest in the subject line, that the
array to pointer conversion is taking place too early, but
simply that it is not taken into consideration in overload
resolution -- it is considered an exact match.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Robert Mabee
Guest





PostPosted: Wed May 17, 2006 9:21 pm    Post subject: Re: Premature Array-to-Pointer Decay Reply with quote



kanze wrote:
Quote:
The problem isn't, as you suggest in the subject line, that the
array to pointer conversion is taking place too early, but
simply that it is not taken into consideration in overload
resolution -- it is considered an exact match.

"array IS-A pointer" seems like a really nasty holdover from C
that leads to undiagnosable bugs such as indexing with a pointer
to a base type when the dynamic type is larger. So, can C++
start evolving towards first-class array types? As a first step,
breaking the ambiguity by considering array <=> pointer to be a
conversion shouldn't break anything much.

---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
kanze
Guest





PostPosted: Thu May 18, 2006 3:21 pm    Post subject: Re: Premature Array-to-Pointer Decay Reply with quote

Robert Mabee wrote:
Quote:
kanze wrote:
The problem isn't, as you suggest in the subject line, that
the array to pointer conversion is taking place too early,
but simply that it is not taken into consideration in
overload resolution -- it is considered an exact match.

"array IS-A pointer" seems like a really nasty holdover from C
that leads to undiagnosable bugs such as indexing with a pointer
to a base type when the dynamic type is larger. So, can C++
start evolving towards first-class array types? As a first step,
breaking the ambiguity by considering array <=> pointer to be a
conversion shouldn't break anything much.

C++ has evolved to have first-class array types. They're
spelled std::vector. It would be nice if boost::array ended up
in the next version of the standard, but generally speaking, I
don't think C style arrays are fixable. (Imagine for a moment
the effect on existing code of removing the array-to-pointer
conversion and giving arrays full value semantics.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Tomás
Guest





PostPosted: Thu May 18, 2006 4:21 pm    Post subject: Four places. Reply with quote

kanze posted:

Quote:
(Imagine for a moment the effect on existing code of removing the
array-to-pointer conversion and giving arrays full value semantics.)


Extremely easy, and without breaking any code.


Decay an array to a pointer to its first element in FOUR places, and make
it remain as an array EVERYWHERE else.


1) When an implicit conversion is wanted:

Example A:

char array[67];

char * p = array;

Example B:

void Func( char * ); /* Declaration */

char array[67];

Func( array );


2) When the dereference operator is applied:

Example A:

char array[67];

char c = *array;


3) For arithmetic, equality, greater than/less than:

Example A:

char array[67];

char *p = array + 56;


Example B:

char array[67]; /* Global object */

bool DetermineIfAhead( const char* const p)
{
return p > array;
}

Example C:

char array[67];
char monkey[43];

bool the_same_address = array == monkey;

bool monkey_ahead = monkey > array;


4) When block brackets are applied:

Example A:

char array[67];

char c = array[6];

/* Which should be translated to:

char c = *(array + 6);
*/



Now my original code should print:

SomeFunc1: Array
SomeFunc2: Array
SomeFunc3: Array

The sooner this goes into the Standard, the sooner C++ improves.


-Tomás

---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Guest






PostPosted: Thu May 18, 2006 6:21 pm    Post subject: Re: Premature Array-to-Pointer Decay Reply with quote

Robert Mabee wrote:
..
Quote:
"array IS-A pointer" seems like a really nasty holdover from C
that leads to undiagnosable bugs such as indexing with a pointer
to a base type when the dynamic type is larger. So, can C++
start evolving towards first-class array types? As a first step,
breaking the ambiguity by considering array <=> pointer to be a
conversion shouldn't break anything much.

Backwards compatibility, not just with C, but with C++ itself, means
that any signfifcant movement along that path is just not feasible.
However, there's a different path to avoiding those problems, and C++
has already taken that path: instead of C-style arrays, use C++
containers.There is not, and should not be, any implicit conversion
from the name of std::vector<> object and an iterator referring to it's
first element.

---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Guest






PostPosted: Thu May 18, 2006 7:21 pm    Post subject: Re: Four places. Reply with quote

Tomás wrote:
Quote:
kanze posted:

(Imagine for a moment the effect on existing code of removing the
array-to-pointer conversion and giving arrays full value semantics.)


Extremely easy, and without breaking any code.


Decay an array to a pointer to its first element in FOUR places, and make
it remain as an array EVERYWHERE else.


1) When an implicit conversion is wanted:

That covers every one of the cases you gave us, which involve the
implicit conversions that occur as the result of a function call, so
such a change wouldn't affect the problem you're complaining about.


---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.