Template function and const array of chars | | |
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. | | | | re: Template function and const array of chars
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 | | | | re: Template function and const array of chars
Tom" <NULL@NULL.NULL> wrote:[color=blue]
> 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.[/color]
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.
[color=blue]
> 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[/color] | | | | re: Template function and const array of chars
Tomás wrote:
[color=blue]
> 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.[/color]
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]
[color=blue]
>
> 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;
> }[/color]
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 | | | | re: Template function and const array of chars
Milan Cvetkovic wrote:[color=blue]
> 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.[/color]
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.
--
Martin | | | | re: Template function and const array of chars
Milan Cvetkovic wrote:[color=blue]
> 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.[/color]
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. |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,449 network members.
|