Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Silly _Generic trick: const_cast(T, exp)

Reply
Thread Tools

Silly _Generic trick: const_cast(T, exp)

 
 
Joel C. Salomon
Guest
Posts: n/a
 
      05-20-2011
Untested, but I think this should work:

#ifdef __cplusplus
#define const_cast(T, exp) const_cast<T>(exp)
#else
#define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
#endif

void foo(void) {
const int i = 42;

// &i is compatible with `const int *` = `int const *`
int *pi = const_cast(int *, &i);

// pi is compatible with `const int const *` = `int const *`
int const *pci = const_cast(int const *, pi);

// fails: types incompatible
double *pd = const_cast(double *, &i);
} /* d--n google groups*/

Disgusting, no?

(Even if this works, it won't be too hard to make it break. Typedef'd pointers will do it: `const vptr` = `void * const` != `void const *`.)

I've got another yucky hack brewing: a reinterpret_cast that casts everything *except* qualifiers.

--Joel
 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      05-20-2011
Joel C. Salomon <(E-Mail Removed)> wrote:
> Untested, but I think this should work:


> #ifdef __cplusplus
> #define const_cast(T, exp) const_cast<T>(exp)
> #else
> #define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
> #endif


What's '_Generic' meant to do? Without knowing that there's no
way to figure out what this is meant to do (or what you expect
it to do).

> I've got another yucky hack brewing: a reinterpret_cast that casts
> everything *except* qualifiers.


I 'm not yet convinced that dragging C++ stuff into C will
work (or will be beneficial). A bit more of context of what
you intent to get from that might be useful...

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      05-20-2011
"Joel C. Salomon" <(E-Mail Removed)> writes:

> Untested, but I think this should work:
>
> #ifdef __cplusplus
> #define const_cast(T, exp) const_cast<T>(exp)
> #else
> #define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
> #endif


I use:

/* Expands to a void expression that checks that POINTER is an
expression whose type is a qualified or unqualified version of
a type compatible with TYPE (a pointer type) and, if not,
causes a compiler warning to be issued (on typical compilers).

Examples:

int *ip;
const int *cip;
const int **cipp;
int ***ippp;
double *dp;

// None of these causes a warning:
CHECK_POINTER_HAS_TYPE (ip, int *);
CHECK_POINTER_HAS_TYPE (ip, const int *);
CHECK_POINTER_HAS_TYPE (cip, int *);
CHECK_POINTER_HAS_TYPE (cip, const int *);
CHECK_POINTER_HAS_TYPE (dp, double *);
CHECK_POINTER_HAS_TYPE (dp, const double *);
CHECK_POINTER_HAS_TYPE (cipp, const int **);
CHECK_POINTER_HAS_TYPE (cipp, const int *const *);
CHECK_POINTER_HAS_TYPE (ippp, int ***);
CHECK_POINTER_HAS_TYPE (ippp, int **const *);

// None of these causes a warning either, although it is unusual to
// const-qualify a pointer like this (it's like declaring a "const int",
// for example).
CHECK_POINTER_HAS_TYPE (ip, int *const);
CHECK_POINTER_HAS_TYPE (ip, const int *const);
CHECK_POINTER_HAS_TYPE (cip, int *const);
CHECK_POINTER_HAS_TYPE (cip, const int *const);
CHECK_POINTER_HAS_TYPE (cipp, const int **const);
CHECK_POINTER_HAS_TYPE (cipp, const int *const *const);
CHECK_POINTER_HAS_TYPE (ippp, int ***const);
CHECK_POINTER_HAS_TYPE (ippp, int **const *const);

// Provokes a warning because "int" is not compatible with "double":
CHECK_POINTER_HAS_TYPE (dp, int *);

// Provoke warnings because C's type compatibility rules only allow
// adding a "const" qualifier to the outermost pointer:
CHECK_POINTER_HAS_TYPE (ippp, const int ***);
CHECK_POINTER_HAS_TYPE (ippp, int *const**);
*/
#define CHECK_POINTER_HAS_TYPE(POINTER, TYPE) \
((void) sizeof ((TYPE) (POINTER) == (POINTER)))

/* Given expressions A and B, both of which have pointer type,
expands to a void expression that causes a compiler warning if
A and B are not pointers to qualified or unqualified versions
of compatible types.

Examples similar to those given for CHECK_POINTER_HAS_TYPE,
above, can easily be devised. */
#define CHECK_POINTER_COMPATIBILITY(A, B) ((void) sizeof ((A) == (B)))

/* Equivalent to casting POINTER to TYPE, but also issues a
warning if the cast changes anything other than an outermost
"const" or "volatile" qualifier. */
#define CONST_CAST(TYPE, POINTER) \
(CHECK_POINTER_HAS_TYPE (POINTER, TYPE), \
(TYPE) (POINTER))

--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
Joel C. Salomon
Guest
Posts: n/a
 
      05-20-2011
On 05/20/2011 06:48 PM, Jens Thoms Toerring wrote:
> Joel C. Salomon <(E-Mail Removed)> wrote:
>> Untested, but I think this should work:

>
>> #ifdef __cplusplus
>> #define const_cast(T, exp) const_cast<T>(exp)
>> #else
>> #define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
>> #endif

>
> What's '_Generic' meant to do? Without knowing that there's no
> way to figure out what this is meant to do (or what you expect
> it to do).


If `exp` is type-compatible with `const T` -- i.e., `exp` is itself of
type `T` or `const T` -- then cast it to type T. Otherwise the (C1x)
compiler will complain of incompatible types.

As the `#ifdef __cplusplus` documents, this is *intended* to be a
work-alike clone of C++'s `const_cast<>`.

>> I've got another yucky hack brewing: a reinterpret_cast that casts
>> everything *except* qualifiers.

>
> I'm not yet convinced that dragging C++ stuff into C will
> work (or will be beneficial). A bit more of context of what
> you intent to get from that might be useful...


Oh, I don't know that it's a *good* idea; I was just opening up the
discussion. Given all the arguments that C++ puts forward for its
`*_cast<>` -- findable with grep, control over exactly what is being
cast away, etc. -- and assuming that C1x gives us the tools to do
something similar, what say we come up with a prototype and discuss it?

--Joel
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      05-20-2011
On 05/21/11 11:29 AM, Joel C. Salomon wrote:
> On 05/20/2011 06:48 PM, Jens Thoms Toerring wrote:
>> Joel C. Salomon<(E-Mail Removed)> wrote:
>>> Untested, but I think this should work:

>>
>>> #ifdef __cplusplus
>>> #define const_cast(T, exp) const_cast<T>(exp)
>>> #else
>>> #define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
>>> #endif

>>
>> What's '_Generic' meant to do? Without knowing that there's no
>> way to figure out what this is meant to do (or what you expect
>> it to do).

>
> If `exp` is type-compatible with `const T` -- i.e., `exp` is itself of
> type `T` or `const T` -- then cast it to type T. Otherwise the (C1x)
> compiler will complain of incompatible types.


So where do we get hold of a C1x compiler?

--
Ian Collins
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-20-2011
(E-Mail Removed) (Jens Thoms Toerring) writes:
> Joel C. Salomon <(E-Mail Removed)> wrote:
>> Untested, but I think this should work:

>
>> #ifdef __cplusplus
>> #define const_cast(T, exp) const_cast<T>(exp)
>> #else
>> #define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
>> #endif

>
> What's '_Generic' meant to do? Without knowing that there's no
> way to figure out what this is meant to do (or what you expect
> it to do).


It's a new feature in the upcoming C201X standard.

See <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1547.pdf>, section
6.5.1.1. (I'm not sure whether that's the latest and/or best C201X
draft.)

[...]

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      05-20-2011
On 05/21/11 10:48 AM, Jens Thoms Toerring wrote:
> Joel C. Salomon<(E-Mail Removed)> wrote:
>> Untested, but I think this should work:

>
>> #ifdef __cplusplus
>> #define const_cast(T, exp) const_cast<T>(exp)
>> #else
>> #define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
>> #endif

>
> What's '_Generic' meant to do? Without knowing that there's no
> way to figure out what this is meant to do (or what you expect
> it to do).
>
>> I've got another yucky hack brewing: a reinterpret_cast that casts
>> everything *except* qualifiers.

>
> I 'm not yet convinced that dragging C++ stuff into C will
> work (or will be beneficial). A bit more of context of what
> you intent to get from that might be useful...


They would be useful for one of the main reasons they are useful in C++:
you can grep for them! An awful lot of casts in C code are necessary
and they can mask errors. An easy way to spot them is a big help.

--
Ian Collins
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-21-2011
Ian Collins <(E-Mail Removed)> writes:
> On 05/21/11 11:29 AM, Joel C. Salomon wrote:
>> On 05/20/2011 06:48 PM, Jens Thoms Toerring wrote:
>>> Joel C. Salomon<(E-Mail Removed)> wrote:
>>>> Untested, but I think this should work:
>>>
>>>> #ifdef __cplusplus
>>>> #define const_cast(T, exp) const_cast<T>(exp)
>>>> #else
>>>> #define const_cast(T, exp) _Generic((exp), const T : (T)(exp))
>>>> #endif
>>>
>>> What's '_Generic' meant to do? Without knowing that there's no
>>> way to figure out what this is meant to do (or what you expect
>>> it to do).

>>
>> If `exp` is type-compatible with `const T` -- i.e., `exp` is itself of
>> type `T` or `const T` -- then cast it to type T. Otherwise the (C1x)
>> compiler will complain of incompatible types.

>
> So where do we get hold of a C1x compiler?


I'm sure they'll become available as quickly as C99 compilers did.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Thoughts on the _Generic feature? Jens Gustedt C Programming 0 10-06-2012 09:03 AM
Nested _Generic selections Joel C. Salomon C Programming 9 01-17-2012 03:03 AM
silly question - what is" Firefox 1.6 alpha 1" ? false-name@false-account.net Firefox 3 09-17-2005 06:49 AM
Silly netscape behaviour.... toedipper Firefox 4 04-03-2005 08:14 PM
Silly question about Wi-Fi Lance Wireless Networking 3 09-13-2004 02:57 PM



Advertisments