[cfe-dev] Preliminary reinterpret_cast Sema patch

Sebastian Redl sebastian.redl at getdesigned.at
Sun Oct 19 05:44:38 PDT 2008


Argiris Kirtzidis wrote:
> Hi Sebastian,
>
> Some comments about the tests:
>
>>   // G++ doesn't like the first two. I disagree with that. /2 allows 
>> casting
>>   // an expression to its own type, subject to all other 
>> restrictions. The only
>>   // restriction mentioned, however, is that casting away constness 
>> is invalid.
>>   // It should therefore be valid to cast a non-pointer type to its 
>> own type,
>>   // no matter how useless that is.
>>   int i = 0;
>>   i = reinterpret_cast<int>(i);
>>   structure s;
>>   s = reinterpret_cast<structure>(s);
>
> These are errors for MSVC and Comeau too. I think the "Subject to the 
> restrictions in this section" refers to the whole 5.2.10 section, not 
> the paragraph.
> See here for another related perspective:
> http://www.archivum.info/comp.std.c++/2006-06/msg00080.html
The thing is, compilers implement a curiously hybrid view of the standard.
5.2.10/1 says that only the explicitly listed conversions are supported.
5.2.10/2 says that conversion to self is allowed, "subject to the 
restrictions in this section". But 5.2.10 contains only two 
restrictions: that of not casting away constness (/2) and that of only 
allowing explicitly listed conversions (/1).
Let's look at the other paragraphs:
/4 allows pointer->integral. Obviously, this can't allow conversion to self.
/5 allows integral->pointer. Same thing.
/6 allows pointer to function to pointer to function "of different 
type". This explicitly disallows conversion to self.
/7 allows pointer to object to pointer to object "of different type". 
Again, conversion to self is explicitly disallowed.
/9 allows pointer to member to pointer to member, if both sides are 
member function or member object types, no mixing. This does not 
explicitly disallow conversion to self, although it was probably 
intended, since it would be in keeping with the spirit of the other two 
paragraphs.

This means that there are, in my opinion, three valid interpretations of 
the standard:
1) Conversion to self is allowed only for pointers to members. This is 
the most literal interpretation.
2) Conversion to self is not allowed at all. This assumes that /9 is in 
the spirit of /6 and /7.
3) Conversion to self is always allowed. This assumes the note in /2 is 
actually normative and the only restriction it talks about is casting 
away constness.

But compilers generally allow conversion to self if the involved types 
are both pointers, or the equivalent reference cast. GCC allows 
int*->int*, but not int->int.

It's easy to follow general practice, of course, but I still think that 
the other compilers are wrong.

>
>>   float *fp = reinterpret_cast<float*>(l);
>>   // Note: should fail on 64-bit, but LLVM is target-agnostic. Is it 
>> possible
>>   // to annotate the bytecode to make this fail in native codegen?
>>   int i = reinterpret_cast<int>(fp);
>
> LLVM IR produced by C/C++ cannot be target-agnostic. See: 
> http://llvm.org/docs/tutorial/LangImpl8.html#targetindep
> You can use TargetInfo to check whether the above conversion is legal.
Sad, but makes sense. How do I get a TargetInfo from the Sema?
>>   fnptr2 fp2 = reinterpret_cast<fnptr2>(fp);
>>   // Should fail in C++03 without extensions, succeed with exts or in 
>> 0x mode.
>>   void *vp = reinterpret_cast<void*>(fp2);
>
> All three compilers accept this; I think Clang should accept it too, 
> programmers will be unpleasantly surprised if they find this is not 
> allowed.
I accept it unless LangInfo.NoExtensions is set. I don't know any switch 
that actually enables this bit, though - I think -std=c++98 should, but 
it doesn't. I can get rid of the NoExtensions check if you think it's 
better.
In addition, I warn if -pedantic is set. This is consistent with GCC's 
behavior.

Sebastian




More information about the cfe-dev mailing list