Topic: conversion from array to reference to pointer
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Fri, 16 Jun 2006 13:34:01 CST Raw View
Greg Herlihy wrote:
> In fact there is no issue with the original program.
Yes, there is!
> Its behavior (returning 0) is as well-defined as it is uninteresting.
No.
> After all, an array argument to reinterpret_cast is automatically converted to a
> pointer first.
Not if the destination type is a reference!
"
5.2.10 Reinterpret cast
[expr.reinterpret.cast]
1 The result of the expression reinterpret_cast<T>(v) is the result
of
converting the expression v to type T. If T is a reference type,
the
result is an lvalue; otherwise, the result is an rvalue and
the
lvalue-to-rvalue (_conv.lval_), array-to-pointer (_conv.array_),
and
function-to-pointer (_conv.func_) standard conversions are
performed
on the the expression v. Types shall not be defined in a
reinter-
pret_cast. Conversions that can be performed explicitly using
rein-
terpret_cast are listed below. No other conversion can be
performed
explicitly using reinterpret_cast.
"
Here, the destination type is a reference type, and, of course, the
array identifier is an lvalue (thus the program is not ill-formed).
Now, what you obtain, is a reference to a pointer.
And the mapping between the reference to the array and the reference to
the pointer is implementation-defined.
It is likely to not change the representation (true with most x86
compilers), in that case, it yields a reference which "refers to" the
first byte of the array (which contains '\0' and is followed by garbage
bytes, probably automatic variables on the stack, or the return address
of the function).
In that case, even if the reinterpret_cast is valid, the subsequent
"return *p" has UB.
And, for instance, it crashes with GCC 4.1.0 on GNU/Linux, compiled
without optimizations (and it is likely to crash with most compilers).
> So v becomes a pointer to char, and then the entire
> expression becomes a char*& cast from a char* argument
>
What do you have in mind?
If the array-to-pointer conversion occured, the char* argument would be
an rvalue, and thus, the reinterpret_cast would fail!
Fortunately, there is no array-to-pointer conversion, and the program
is well-formed (but this reintepret_cast is a very bad idea).
---
[ 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 ]
Author: "Yusuf Jakoet" <yusuf.jakoet@gmail.com>
Date: Fri, 9 Jun 2006 09:37:46 CST Raw View
#include <iostream>
int main(void)
{
char array[] = {'a', 'b', 'c'};
char *ptr = "def";
char* const &p = reinterpret_cast<char* const &>(array);
char* const &q = reinterpret_cast<char* const &>(ptr);
char *& p1 = reinterpret_cast<char*&>(array);
char *& q1 = reinterpret_cast<char*&>(ptr);
// If p is a reference to a pointer, then it should be used
// just as a normal pointer.
printf("%c %c %c\n", p, p+1, p+2);
// If p is a reference to a pointer, then it should be used
// just as a normal pointer.
printf("%c %c %c\n", q[0], q[1], q[2]);
// If p is a reference to a pointer, then it should be used
// just as a normal pointer.
printf("%c %c %c\n", p1, p1+1, p1+2);
// If p is a reference to a pointer, then it should be used
// just as a normal pointer.
printf("%c %c %c\n", q1[0], q1[1], q1[2]);
// If p really is a reference, then this line shouldn't compile.
// p = 0;
// If q really is a reference, then this line shouldn't compile.
// q = 0;
// If p1 really is a reference, then this line shouldn't compile.
p1 = 0;
// If q1 really is a reference, then this line shouldn't compile.
q1 = 0;
// The previous lines compile, hence they aren't references!
return (int)p;
}
uvts_cvs@yahoo.com wrote:
> Hi everybody do you think this little chunk of code is legal and leads
> to defined results?
>
> int main()
> {
> char v[] = "";
> char *const& p = reinterpret_cast<char*const&>(v);
> return *p;
> }
>
> And the next one?
>
> int main()
> {
> char v[] = "";
> char *& p = reinterpret_cast<char*&>(v);
> return *p;
> }
>
> Bye, Daniele.
>
> ---
> [ 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 ]
---
[ 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 ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Fri, 9 Jun 2006 11:03:46 CST Raw View
uvts_cvs@yahoo.com wrote:
> Hi everybody do you think this little chunk of code is legal and leads
> to defined results?
> int main()
> {
> char v[] = "";
> char *const& p = reinterpret_cast<char*const&>(v);
Legal. v is an lvalue with type char[1]. The standard says
that you can use reinterpret_cast to convert any lvalue to a reference
of any other type (practically). Of course, since v isn't a pointer, p
(which refers to it) can't be accessed.
> return *p;
And this is undefined behavior. Logically, you've taken the address of
v, and told the compiler that the data at that address is a pointer.
Which you then dereference. You can't just take any random memory
address, tell the compiler its a pointer, and then deference it.
> }
> And the next one?
> int main()
> {
> char v[] = "";
> char *& p = reinterpret_cast<char*&>(v);
> return *p;
> }
No difference.
Note that these examples are syntactically legal only because the
compiler has no reason to apply the array-to-pointer conversion. I
would not be surprised if some compilers applied it anyway, and said
that the code was illegal, because you are trying to convert a
non-lvalue to a reference (which isn't allowed in a reinterpret_cast).
--
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 ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Fri, 9 Jun 2006 23:05:19 CST Raw View
Yusuf Jakoet wrote:
> #include <iostream>
>
> int main(void)
> {
> char array[] = {'a', 'b', 'c'};
> char *ptr = "def";
>
> char* const &p = reinterpret_cast<char* const &>(array);
> char* const &q = reinterpret_cast<char* const &>(ptr);
>
> char *& p1 = reinterpret_cast<char*&>(array);
> char *& q1 = reinterpret_cast<char*&>(ptr);
>
...
> // If p1 really is a reference, then this line shouldn't compile.
> p1 = 0;
> // If q1 really is a reference, then this line shouldn't compile.
> q1 = 0;
>
> // The previous lines compile, hence they aren't references!
Sure they are: p1 and q1 are both references to pointers; each one can
therefore be assigned a char * pointer value - including the null
pointer constant (0).
Now attempting to assign an integer to either p1 or q1 would be a
different matter:
// If p1 really is a reference, then this line shouldn't compile.
p1 = 1; // error
// If q1 really is a reference, then this line shouldn't compile.
q1 = 1; // error
In fact there is no issue with the original program. Its behavior
(returning 0) is as well-defined as it is uninteresting. After all, an
array argument to reinterpret_cast is automatically converted to a
pointer first. So v becomes a pointer to char, and then the entire
expression becomes a char*& cast from a char* argument - which is one
of the types of casts that reinterpet_cast performs.
Greg
---
[ 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 ]
Author: "Yusuf Jakoet" <yusuf.jakoet@gmail.com>
Date: Mon, 12 Jun 2006 09:36:53 CST Raw View
Sorry. I was relating references to const variables, thinking that
references cannot be changed onced assigned.
So the difference at all between the previous code blocks would only be
the use of the const specifier?
Greg Herlihy wrote:
> Sure they are: p1 and q1 are both references to pointers; each one can
> therefore be assigned a char * pointer value - including the null
> pointer constant (0).
>
> Now attempting to assign an integer to either p1 or q1 would be a
> different matter:
>
> // If p1 really is a reference, then this line shouldn't compile.
> p1 = 1; // error
>
> // If q1 really is a reference, then this line shouldn't compile.
> q1 = 1; // error
>
> In fact there is no issue with the original program. Its behavior
> (returning 0) is as well-defined as it is uninteresting. After all, an
> array argument to reinterpret_cast is automatically converted to a
> pointer first. So v becomes a pointer to char, and then the entire
> expression becomes a char*& cast from a char* argument - which is one
> of the types of casts that reinterpet_cast performs.
>
> Greg
---
[ 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 ]
Author: uvts_cvs@yahoo.com
Date: Tue, 6 Jun 2006 09:24:11 CST Raw View
Hi everybody do you think this little chunk of code is legal and leads
to defined results?
int main()
{
char v[] = "";
char *const& p = reinterpret_cast<char*const&>(v);
return *p;
}
And the next one?
int main()
{
char v[] = "";
char *& p = reinterpret_cast<char*&>(v);
return *p;
}
Bye, Daniele.
---
[ 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 ]