Re: Detecting if type is char*

Tech-Archive recommends: Fix windows errors by optimizing your registry



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
.



Relevant Pages

  • Detecting if type is char*
    ... I want to disallow using sizeof on type char*, by providing a template ... enum; ... struct IsCharPointer ... The idea is that I don't want to allow sizeof to be used on char*, ...
    (microsoft.public.vc.language)
  • SSPI Kerberos for delegation
    ... const char *tokenSource, const char *name = NULL, ... DWORD bufsiz = sizeof buf; ... int n = ib.cbBuffer; ... // wserr() displays winsock errors and aborts. ...
    (microsoft.public.dotnet.framework.remoting)
  • injection_projection code
    ... because of hex encoding. ... a row in the template. ... Sanitize string to protect against email header injection. ... void injection_protection(char *s) ...
    (freebsd-isp)
  • Re: Sizeof question
    ... |> | sizeof returns the number of chars that array occupies. ... | On the most common system, a char is 1 byte though. ... operand, which may be an expression or the parenthesized ... operand is a variable length array type, ...
    (alt.comp.lang.learn.c-cpp)
  • How to get the PID and VID of a USB Mass Storage Device
    ... char driveName; ... memset (buffer, 0, sizeof (buffer)); ... char serialNumber; ...
    (microsoft.public.development.device.drivers)