Template function and const array of chars

M

Milan Cvetkovic

Hi,

Recently I came accross a weird bug in my code which turned to be my
missunderstanding of arrays in C++. It all boils down to the small example:


template<class ITER>
const char* gggg (ITER value)
{
return value;
}

int main (int /*argc*/, char* /*argv*/[])
{
const char array[] = "ABCD";
const char* p1 = gggg(array);
const char* p2 = gggg(array+0);
if (p1 == p2)
return 0;
else
return 1;
}

This program will report different results when compiled with different
compiler. In particular, g++-2.95.2 returns 1 (pointers are not equal)
and g++-4.1 returns 0 (pointers are equal).

Is this a compiler bug in 2.95.2, or the C++ spec allows the compiler do
this funny stuff.

Thanks, Milan.
 
T

Tomás

template<class T>
const char* TakeByValueAndConvertToCharPointer (T object)
{
return object;
}

int main()
{
char const array[] = "ABCD";

/*
Right now, we have an array in
memory that looks like as follows:

-------------------------------
| 'A' | 'B' | 'C' | 'D' | 0 |
-------------------------------

*/

const char* p1 = gggg(array);

//In the above line, you've just passed an array by value.
//If memory serves me right, that's dodgy.

const char* p2 = gggg(array+0);

//In the above line, it looks like "array" will decay to
//an expression of type "const char*", and then zero will
//be added to it.

if (p1 == p2)
return 0;
else
return 1;
}

-Tomás
 
M

Milan Cvetkovic

Tom said:
const char* p1 = gggg(array);

//In the above line, you've just passed an array by value.
//If memory serves me right, that's dodgy.

I don't know what exactly you mean by "dodgy".
Isn't this usage same as when you write:

printf ("This is a string\n");

The function gggg is instantiated with <const char*> as a parameter, in
both invocations. The value of parameter passed depends on:
- compiler used; and
- the invocation (arrray or array+0)

Milan.
template<class T>
const char* gggg (T object)
{
return object;
}

int main()
{
char const array[] = "ABCD";

/*
Right now, we have an array in
memory that looks like as follows:

-------------------------------
| 'A' | 'B' | 'C' | 'D' | 0 |
-------------------------------

*/

const char* p1 = gggg(array);

//In the above line, you've just passed an array by value.
//If memory serves me right, that's dodgy.

const char* p2 = gggg(array+0);

//In the above line, it looks like "array" will decay to
//an expression of type "const char*", and then zero will
//be added to it.

if (p1 == p2)
return 0;
else
return 1;
}

-Tomás
 
T

Thomas Tutone

Tomás said:
template<class T>
const char* TakeByValueAndConvertToCharPointer (T object)
{
return object;
}

int main()
{
char const array[] = "ABCD";

/*
Right now, we have an array in
memory that looks like as follows:

-------------------------------
| 'A' | 'B' | 'C' | 'D' | 0 |
-------------------------------

*/

const char* p1 = gggg(array);

//In the above line, you've just passed an array by value.

No, arrays can't be passed by value directly - one would have to wrap
it in a class to do so. Just the decayed pointer will be passed.

[snip]
const char* p2 = gggg(array+0);

//In the above line, it looks like "array" will decay to
//an expression of type "const char*", and then zero will
//be added to it.

if (p1 == p2)
return 0;
else
return 1;
}

Sorry to be dense, but I'm missing your point. Based on your analysis,
should the program return 0 or 1? That was the OP's question.

Best regards,

Tom
 
M

Martin Vejnar

Milan said:
template<class ITER>
const char* gggg (ITER value)
{
return value;
}

int main (int /*argc*/, char* /*argv*/[])
{
const char array[] = "ABCD";
const char* p1 = gggg(array);
const char* p2 = gggg(array+0);
if (p1 == p2)
return 0;
else
return 1;
}

This program will report different results when compiled with different
compiler. In particular, g++-2.95.2 returns 1 (pointers are not equal)
and g++-4.1 returns 0 (pointers are equal).

Is this a compiler bug in 2.95.2, or the C++ spec allows the compiler do
this funny stuff.

As far as I can tell, both calls refer to the same function 'gggg<const
char *>(const char *)' and supply it with the same arguments. 'p1' and
'p2' should be equal.

On VS8.0, 'main' returns 0.

I'd say it's a compiler bug; the old g++ may have problems deducing
correct template arguments.
 
A

AnalogFile

Milan said:
Hi,

Recently I came accross a weird bug in my code which turned to be my
missunderstanding of arrays in C++. It all boils down to the small example:


template<class ITER>
const char* gggg (ITER value)
{
return value;
}

int main (int /*argc*/, char* /*argv*/[])
{
const char array[] = "ABCD";
const char* p1 = gggg(array);
const char* p2 = gggg(array+0);
if (p1 == p2)
return 0;
else
return 1;
}

This program will report different results when compiled with different
compiler. In particular, g++-2.95.2 returns 1 (pointers are not equal)
and g++-4.1 returns 0 (pointers are equal).

Is this a compiler bug in 2.95.2, or the C++ spec allows the compiler do
this funny stuff.

I guess G++-2.95.2 failed to comply with 14.8.2.1/2 and instantiated the
first call with the wrong type.

I guess you can test this by forcing an error and looking at the
compiler diagnostics. For example try

template<class ITER>
const char* gggg (ITER value)
{
value = 1;
return value;
}

since there's no cast it should give an error and tell you what type
ITER it's trying to instantiate.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top