Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » C++

arrays and cv qualification conversions

 
Jump to:  
 
Christof Meerwald
PostPosted: Sat Sep 06, 2008 8:24 pm    Post subject: arrays and cv qualification conversions
       
Hi,

consider the following program:

void f1(char *a[][2])
{ }

void f2(char * const a[][2])
{ }

void f3(const char * const a[][2])
{ }

int main()
{
char *a[1][2];

f1(a);
f2(a);
f3(a);
}

which of these function calls (conversions) are legal?

Most compilers appear to be happy with f2 (g++ 4.2, Visual C++ 2008, Sun
Studio 12, Digital Mars C++, HP aCC), but only Digital Mars and Sun Studio
will accept f3.

Can anyone point me to the section in the C++ standard where it allows these
conversions?


Christof

--
LINK sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org

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

 
Jiang
PostPosted: Tue Sep 09, 2008 11:58 am    Post subject: Re: arrays and cv qualification conversions
       
On Sep 7, 5:24 am, Christof Meerwald <NOSPAM-seeMySig
+ue...@usenet.cmeerw.org> wrote:
Quote:
Hi,


Understand the argument types help here in my mind.

Quote:
consider the following program:

void f1(char *a[][2])
{ }


f1's argument type

a is array of an 2-elements-array,
and the elements are pointer to char

Here the first bound const is omitted, which means,
the first dimension is free.


Quote:

void f2(char * const a[][2])
{ }


f2's argument type

a is array of an 2-elements-array,
and the elements are const pointer to char

Note here the "const" is applied to the array,
further applied to the elements of the array.
See 3.9.3/p5 for details.

Quote:

void f3(const char * const a[][2])
{ }


f3's argument type

a is array of an 2-elements-array,
and the elements are const pointer to const char


Now let's see your array definition and function calls.

Quote:
int main()
{
char *a[1][2];


You defined an array, and the type

a is an array with only 1 element,
and the element is array of 2 pointer to char


Quote:
f1(a);


Legal function call.

compiler can do the exact match using array-pointer
conversion.


Quote:
f2(a);

Again, legal function call.

Although you did not provide the const specifier
in your array definition, the compiler can will
use qualification conversion for resolution
defined in 13.3.3. This is also a exact match.

For qualification conversion(4.4), it is required
that an rvalue of type "pointer to cv1 T" can be
converted to an rvalue of type "pointer to cv2 T"
if "cv2 T" is more cv-qualified than "cv1 T".
For your example, cv1 is "no cv-qualifier" and
cv2 is "const", therefore we see the conversion
is reasonable according to 3.9.3/p4.


Quote:
f3(a);

Well, the compiler will have trouble dealing with
this beast. Actually this call is illegal.

f3 requires both the array (underlying elements)
and the *contents*, pointed by the element
pointers, should be const. In 13.3.3, we do not
have any valid conversion defined to do that.
More specifically, qualification conversion can
not applied recursively for "layered indirections".

Quote:
}

which of these function calls (conversions) are legal?



f1 and f2.

f3 is ill-formed.


Quote:
Most compilers appear to be happy with f2 (g++ 4.2, Visual C++ 2008, Sun
Studio 12, Digital Mars C++, HP aCC), but only Digital Mars and Sun Studio
will accept f3.

Can anyone point me to the section in the C++ standard where it allows these
conversions?

For f1 and f2, see my above explanation, the diagnostic for f3
can be induced from these rules in my mind.

Quote:
Christof

Regards,

Jiang


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

 
Christof Meerwald
PostPosted: Tue Sep 09, 2008 10:10 pm    Post subject: Re: arrays and cv qualification conversions
       
On Tue, 9 Sep 2008 05:58:49 CST, Jiang wrote:
Quote:
On Sep 7, 5:24 am, Christof Meerwald <NOSPAM-seeMySig
+ue...@usenet.cmeerw.org> wrote:
Understand the argument types help here in my mind.

While I don't necessarily agree with every part of your explanation (as I
don't see why overload resolution would be relevant here), I think I got the
idea. I think it becomes much more obvious when introducing a typedef for
the array:

typedef char *Array[2];

Quote:
void f1(char *a[][2])

this would then be equivalent to:

void f1(Array *a)

Quote:
void f2(char * const a[][2])

and (because a const qualifier for the array applies to the element type)
this is equivalent to:

void f2(const Array *a)


and then it's obvious that "Array *" can be converted to "const Array *".


Christof

--
LINK sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org

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

 
Jiang
PostPosted: Thu Sep 11, 2008 5:04 am    Post subject: Re: arrays and cv qualification conversions
       
On Sep 10, 7:10 am, Christof Meerwald <NOSPAM-seeMySig
+uz...@usenet.cmeerw.org> wrote:
Quote:
On Tue, 9 Sep 2008 05:58:49 CST, Jiang wrote:
On Sep 7, 5:24 am, Christof Meerwald <NOSPAM-seeMySig
+ue...@usenet.cmeerw.org> wrote:
Understand the argument types help here in my mind.

While I don't necessarily agree with every part of your explanation (as I
don't see why overload resolution would be relevant here),

Same here. :-(

I don't know why I quoted rules for overloading in my previous late-
night
post. Seems I should go to bed instead of post here in the late night.

For your example, standard conversions only will be enough and
I apologize for the confusion I've made.


Quote:
I think I got the
idea. I think it becomes much more obvious when introducing a typedef for
the array:

typedef char *Array[2];


Which is true in my mind.

A short summary for your question:

1. f1 is legal because using array-to-pointer conversion.

2. Because we have another standard conversion, qualification
conversion,
therefore f2 is also well-formed.

3. f3 is not legal because we can not find exact match and necessary
standard conversions to make it legal.

and,

4. Using typedef for multi-level declaration is sometimes useful.
(but we still must be careful where the const specifiers are)


Regards,

Jiang


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

 
blargg
PostPosted: Sat Sep 13, 2008 8:32 pm    Post subject: Re: arrays and cv qualification conversions
       
In article <slrngc50ef.jqv.NOSPAM-seeMySig@msgid.cmeerw.org>,
Christof Meerwald <NOSPAM-seeMySig+ue45+@usenet.cmeerw.org> wrote:

Quote:
consider the following program:
[shortened]
void f1(char *a[][2]);
void f2(char * const a[][2]);
void f3(const char * const a[][2]);

int main()
{
char *a[1][2];

f1(a);
f2(a);
f3(a);
}

which of these function calls (conversions) are legal?

Most compilers appear to be happy with f2 (g++ 4.2, Visual C++ 2008, Sun
Studio 12, Digital Mars C++, HP aCC), but only Digital Mars and Sun Studio
will accept f3.

Can anyone point me to the section in the C++ standard where it allows these
conversions?

First, let's eliminate the implicit array-to-pointer nonsense, since
that's not at the heart of your question:

void f1(char * (*a)[2]); // pointer to char * [2]
void f2(char * const (*a)[2]); // pointer to char * const [2]
void f3(const char * const (*a)[2]); // pointer to const char* const [2]

int main()
{
char* aa [2];
char* (*a) [2] = aa; // pointer to char* [2]
f1(a);
f2(a);
f3(a);
}

All three calls are valid as far as I can tell. The first doesn't
involve any conversion. The second simply converts from pointer-to-T to
pointer-to-const-T, clearly valid. The third is the tricky one, and
valid as far as I can tell. See section 4.4 Qualification Conversions,
paragraph 4. In summary, you can add const (and volatile) at any
"depth", as long as you also add const to all shallower levels. As
stated in the standard, this is to ensure that const safety isn't
implicitly violated. The reasoning is that when you add it at some
level, it's not there in the caller's type therefore if the pointer were
changed to point to a const object, the caller could modify it.
Therefore, const must be added to all shallower levels to prevent the
callee from changing anything. Examining f3(), one can see that there's
no way const safety can be violated without a cast. If we added f4()

void f4(const char * (*a)[2]); // pointer to const char* [2]

calling it would be in error, since it could do (*a) [0] = "foo", and
then the main(0 could attempt to modify the string's contents by doing
(*a) [0] [0] = 'X', all without any const_cast.

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

 
Jiang
PostPosted: Sun Sep 14, 2008 5:30 pm    Post subject: Re: arrays and cv qualification conversions
       
On Sep 14, 5:32 am, blargg <blargg....@gishpuppy.com> wrote:
Quote:
In article <slrngc50ef.jqv.NOSPAM-seeMy...@msgid.cmeerw.org>,
Christof Meerwald <NOSPAM-seeMySig+ue...@usenet.cmeerw.org> wrote:



consider the following program:
[shortened]
void f1(char *a[][2]);
void f2(char * const a[][2]);
void f3(const char * const a[][2]);

int main()
{
char *a[1][2];

f1(a);
f2(a);
f3(a);
}

which of these function calls (conversions) are legal?

Most compilers appear to be happy with f2 (g++ 4.2, Visual C++ 2008, Sun
Studio 12, Digital Mars C++, HP aCC), but only Digital Mars and Sun Studio
will accept f3.

Can anyone point me to the section in the C++ standard where it allows these
conversions?

First, let's eliminate the implicit array-to-pointer nonsense, since
that's not at the heart of your question:



Huh? why the above conversion is nonsense? Without such a good, old
conversion, none of the OP's function calls is valid.

Please note rules are rules, there are no so-called first-class rules
or second-class rules. If you feel some rules are special, then the
only thing I can see is, well, you are not familiar with them.

-> Actually your example code proves my words. :-)


Quote:
void f1(char * (*a)[2]); // pointer to char * [2]
void f2(char * const (*a)[2]); // pointer to char * const [2]
void f3(const char * const (*a)[2]); // pointer to const char* const [2]

int main()
{
char* aa [2];
char* (*a) [2] = aa; // pointer to char* [2]

[...]


1. The above code/conversion is ill-formed.
Ask here if you can not find the reason.

2. Compared with the OP's question, your example has different
semantics and also I do not find how your explanation
contributes on the better understanding for this topic.


Regards,

Jiang


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

 
blargg
PostPosted: Mon Sep 15, 2008 2:51 am    Post subject: Re: arrays and cv qualification conversions
       
In article
<ce6f32c9-fb11-478f-8e69-5ac0442a1cca@a8g2000prf.googlegroups.com>,
Jiang <goo.mail01@yahoo.com> wrote:
Quote:
On Sep 14, 5:32 am, blargg <blargg....@gishpuppy.com> wrote:
In article <slrngc50ef.jqv.NOSPAM-seeMy...@msgid.cmeerw.org>,
Christof Meerwald <NOSPAM-seeMySig+ue...@usenet.cmeerw.org> wrote:
consider the following program:
[shortened]
void f1(char *a[][2]);
void f2(char * const a[][2]);
void f3(const char * const a[][2]);
int main()
{
char *a[1][2];

f1(a);
f2(a);
f3(a);
}
[...]
First, let's eliminate the implicit array-to-pointer nonsense, since
that's not at the heart of your question:

Huh? why the above conversion is nonsense? Without such a good, old
conversion, none of the OP's function calls is valid.

I meant the fact that

void f1(char *a[][2]);

is treated by the compiler as if it were

void f1(char *(*a)[2]);

I don't think this equivalence was at the heart of the original poster's
question, so I rewrote the functions to just say directly what they were
really taking. I also was removing the array-to-pointer-to-first-element
conversion that was occurring elsewhere, since that was also
complicating matters. I understood the poster to be asking about the
differing const usage in the three functions, and whether some or all
were valid, and why.

Quote:
Please note rules are rules, there are no so-called first-class rules
or second-class rules. If you feel some rules are special, then the
only thing I can see is, well, you are not familiar with them.


I have no idea what you're talking about here. Where did I mention
first-class and second-class rules in my message? Are you referring to
the fact that I started my message with "First,"?

Quote:
-> Actually your example code proves my words. Smile


Proves what? I'm not following what you mean. And why the condescension?
I don't think it's warranted.

Quote:
void f1(char * (*a)[2]); // pointer to char * [2]
void f2(char * const (*a)[2]); // pointer to char * const [2]
void f3(const char * const (*a)[2]); // pointer to const char* const [2]

int main()
{
char* aa [2];
char* (*a) [2] = aa; // pointer to char* [2]
[...]
1. The above code/conversion is ill-formed.
Ask here if you can not find the reason.

OK, I left out & before aa. The point of the example was the calls to
f1, f2, and f3.

Quote:
2. Compared with the OP's question, your example has different
semantics and also I do not find how your explanation
contributes on the better understanding for this topic.

The only other difference is that I made 'a' in main() a pointer to
char* [2], which is what it was decaying to anyway when passed to any of
the functions. I felt it was clearer to remove the implicit
array-to-pointer conversion, since that seemed irrelevant to the const
issue. Perhaps you're saying that this implicit conversion was making
section 4.4 not even apply?

Are we at least in agreement of the following lines?

char** p = 0;

char * const* p2 = p; // OK
char const* const* p3 = p; // OK
char const* * p4 = p; // error

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

Page 1 of 1 .:.

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 ©

regeneracja części caterpillar gerda zabawki edukacyjne poker ogrzewanie