Re: Conversion operator not being picked up by compiler
Re: Conversion operator not being picked up by compiler
- Subject: Re: Conversion operator not being picked up by compiler
- From: Steve Checkoway <email@hidden>
- Date: Sat, 14 Jan 2006 04:14:39 -0800
On Jan 13, 2006, at 12:58 PM, Greg Norz wrote:
| Hi,
| (rushed answer:)
| I don't *think* code is not well-formed because foo
| (type Foo) is passed to a variadic (...) function parameter.
| The compiler can't deduce from your format string "%s" that a
| 'const char*' is sought, and thus doesn't know to look for an
| implicit-conversion.
Well, in my opinion, it shouldn't matter that I HAPPEN to want a
'const
char*'. To me, the only concern is that the compiler wants a POD type,
and I'm giving it a POD type via a conversion operator. Let's say
that I
modify 'class Foo' to convert to different types of data, such that I
have 'operator int()' and 'operator wchar_t*()' and 'operator double
()'.
All of those are POD types and the compiler should know enough to
check
an object for those types of conversions. I guess in that case,
though,
you would NEED a 'static_cast<>' because the compiler may not be smart
enough to know which conversion operator you really want. I would
totally understand that error, and a cast would be totally
warranted to
inform the compiler as to the true intentions of the code.
I think you hit it right there. The compiler has no way to know which
implicit conversion operator you want to use. I suppose you could
argue that since there is only one user defined conversion, it should
be used but my guess (without digging out the standard) is that c++
does not say anything about implicit conversions here.
Were you use use:
const char *s = foo;
Write( "%s", s );
then it should work.
What I wish would happen when you pass a nonPOD to a variadic
function is that gcc would emit an error rather than a warning that
your code will abort at run time.
Also, consider when you perform a standard 'printf' :
const char* someStr = "Hello";
const long someNum = 42;
printf( "Some number = %d, some string = %s", someStr, someNum );
Unless you have some special compiler type checking enabled (which I
think Xcode has), the compiler won't warn you that you've mixed up
your
types in the varargs portion of 'printf'. All the compiler cares about
at that point is the fact that you gave it POD types that it can
easily
work with.
If you want that checking in your own code (and you're using gcc),
you can use:
void Write( const char *msg, ... ) __attribute__((format(__printf__,
1,2)));
void Write( const char *msg, ... )
{
std::cout << msg << std::endl;
}
If you need portable code, this works well:
#if defined(__GNUC__)
#define PRINTF(a,b) __attribute__((format(__printf__,a,b)))
#else
#define PRINTF(a,b)
#endif
void Write( const char *msg, ... ) PRINTF(1,2);
...
It just seems to me that gcc is not looking at objects to see if they
have conversions to a POD type. This code works on Visual C++ 7.1, and
my guess there is that they don't do any checking whatsoever. In fact,
I'm 99% sure that's the case because I've caught errors in the past
where I pass a 'std::string' into a '*printf' function and received
the
address of the variable.
I've also heard that VC++ also allows passing a CString and
converting that for you. Perhaps it's the same thing, implicit
conversion.
The static_cast<> is fine by me. It at least compiles the code and
appears to allow it to run correctly. I just think that gcc should be
checking conversion operators in the future before saying that code
will
abort at runtime. Unless, of course, I'm using the conversion
operators
incorrectly in my example, in which case I stand corrected! :^)
Using the static_cast<> works and is correct according to the
standard. If you really think that gcc has a bug, you should file
one. If gcc does not have a bug and it's following the standard, then
you could always try to get it into the next version of the standard.
One final comment : I have some other compilers at home (CodeWarrior,
Intel C++ for Windows) that I might try to see how they handle it. It
would be interesting to compare the results.
Maybe it would be interesting. At the end of the day though, you have
to work with the tools you're planning to use. If writing standard-
compliant code is your goal, then you should restrict yourself to
that no matter how many cool things you can do with a particular
compiler's extension. If writing portable code is your goal then you
have to work quite a bit harder and write code to the lowest common
denominator.
- Steve
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden