Re: Detecting if type is char*
- From: "Tom Widmer [VC++ MVP]" <tom_usenet@xxxxxxxxxxx>
- Date: Tue, 14 Mar 2006 12:33:14 +0000
Daniel Lidström wrote:
Hello!
I want to disallow using sizeof on type char*, by providing a template
function called safe_sizeof.
sizeof is an operator, not a function. The important things about it are that the "parameter" is never actually evaluated and that the result is a compile time constant. Your implementation fails to emulate sizeof on both these counts. It seems to me that you want sizeof to work with everything that isn't an array, not just everything that isn't a char pointer. Here's a possibility:
namespace impl
{
template <class T>
char (&safe_sizeof(T const& t))[sizeof(T)];
template <class T>
struct ERROR_do_not_use_pointer_in_SAFE_SIZEOF safe_sizeof(T*);
}
#define SAFE_SIZEOF(t) sizeof(::impl::safe_sizeof(t))
int const* p;
char array[SAFE_SIZEOF(p)];
Unfortunately this kills the compiler on VC7.1 with an ICE, but it may work on 8 (I haven't currently got it installed, the code does work on GCC).
Anyway, to fix your version, read on:
Here is my attempt:
template<class T>
struct IsCharPointer
{
enum { value = false };
};
template<>
struct IsCharPointer<char*>
{
enum { value = true };
};
template<>
struct IsCharPointer<char const*>
{
enum { value = true };
};
//in principle should add volatile too
template<bool> struct CompileTimeChecker
{
CompileTimeChecker(...);
};
template<> struct CompileTimeChecker<false> { };
template<class T>
size_t safe_sizeof(T arr)
That should be:
template<class T>
size_t safe_sizeof(T const& arr) //prevent array-to-pointer conversion
{
class ERROR_Do_Not_Use_Sizeof_On_CharP { };
sizeof(CompileTimeChecker<!IsCharPointer<T>::value>(ERROR_Do_Not_Use_Sizeof_On_CharP()));
return sizeof(arr);
}
The idea is that I don't want to allow sizeof to be used on char*, but only
on other types, including char[]. The problem is that char[] is converted
to char* when passed to safe_sizeof so there is an error.
Yes, this is the standard array-to-pointer conversion, which you can avoid by using a reference.
If I provide a
specialization of safe_sizeof on char[] then there is no error, but the
return value is wrong. For example:
template<>
size_t safe_sizeof(char arr[])
char arr[] is the same as char* arr.
{
return sizeof(arr);
}
if I now do:
char e[20];
int k = safe_sizeof(e);
k is 4.
Is there a way to accomplish what I want?
If you can get my version to compile, I think it is preferable, but otherwise use a reference.
Tom
.
- Follow-Ups:
- Re: Detecting if type is char*
- From: Tom Widmer [VC++ MVP]
- Re: Detecting if type is char*
- References:
- Detecting if type is char*
- From: Daniel Lidström
- Detecting if type is char*
- Prev by Date: Re: Dll error
- Next by Date: Re: Detecting if type is char*
- Previous by thread: Re: Detecting if type is char*
- Next by thread: Re: Detecting if type is char*
- Index(es):
Relevant Pages
|