Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #41351

Re: Few questions about casting away const.

From James Kuyper <jameskuyper@verizon.net>
Newsgroups comp.lang.c
Subject Re: Few questions about casting away const.
Date 2014-03-04 15:18 -0500
Organization Self
Message-ID <53163527.2090509@verizon.net> (permalink)
References <lf4cq3$mie$1@speranza.aioe.org>

Show all headers | View raw


On 03/04/2014 06:18 AM, Daniel wrote:
> const char *s = "abc";
> char *t = s;
> 
> printf("%s", s);
> 
> 
> Firstly, the direct cast from 'const char *' to 'char *' which is seen on 
> the second line. 

There is no cast on that line.

> ... I've read that this is illegal in standard C, is that 
> true?

That line violates the constraint in section 6.5.16.1p1, which says that
at least one of several permitted cases should apply whenever there's an
assignment expression. Your code doesn't match any of those cases. The
case that comes closest to matching is the one where the left and right
operands both have pointer type - but it also requires that the type
pointed at by the left operand have all of the same qualifiers (const,
restrict, volatile, or _Atomic) as the type pointed at by the right
operand. 's' points at a type with the 'const' qualifier, which the type
pointed at by 't' does not have.

> Secondly, given that printf's 's' specifier matches a 'char *', the 
> comment in section 6.5.2.2p6 of C11 seems to indicate that these types 
> are interchangeable in this situation. ...

Everything it says in 6.5.2.2p6 is conditioned by the first sentence:
"If the expression that denotes the called function has a type that does
not include a prototype, ...". That would apply only if you did not
provide a prototype for printf(), either explicitly or by #include
<stdio.h>.6.5.2.2p6 goes on to say "If the function is defined with a
type that includes a prototype, and ... the prototype ends with an
ellipsis (, ...) or the types of the arguments after promotion are not
compatible with the types of the parameters, the behavior is undefined."

printf() doesn't have to be written in C, but for the purposes of
6.5.2.2p6, it should be considered as having been defined in the fashion
given in 7.21.6.3p1:

	int printf(const char * restrict format, ...);

Since the definition of printf() ends in ellipses, if 6.5.2.2p6 is
applicable, any call to printf() has undefined behavior - therefore I
strongly recommend NOT making it applicable - the simplest way of doing
so is to add:

#include <stdio.h>

but even if 6.5.2.2p6 were applicable, I don't seen how you reached the
conclusion that it says that char* and const char* should be
interchangeable. char* is not compatible with const char* (6.7.3p10,
6.7.6.1p2), so the behavior would still be undefined even if printf()
were not a variadic function.

> ... If the direct cast is invalid, 
> would this be a legal alternative?:
> 
> 
> #define unconst(p) (unconst_(0, p))
> 
> char *unconst_(int unused, ...)
> {
>         va_list args;
>         char *r;
> 
>         va_start(args, unused);
>         r = va_arg(args, char *);
>         va_end(args);
>         return r;
> }
>  
> const char *s = "abc";
> char *t = unconst(s);

All you've done is turned off the mandatory diagnostic. Since const
char* is not compatible with char*, calling unconst(s) results in an
invocation of va_arg() that gives your program undefined behavior
(7.16.1.1p2).

> Or, are there other possibilities?

There's no need to jump through all of those hoops. If you want to
convert a const char* into a char*, just use a cast (the real thing, not
what you thought you were doing on the second line of your code):

	char *t = (char*)s;

This removes the constraint violation, and (unlike your use of
unconst()) does not, in itself, have undefined behavior. However, it
creates the likelihood of writing code with undefined behavior later on
in the same program.

Use of a string literal causes the creation of an unnamed array of char
containing the specified characters.  Attempting to modify those
characters would give your program undefined behavior (6.4.5p7).
Therefore, it should properly have been an array of const char, but
'const' was not added to the language until it was first standardized,
by which time there was already far too much existing code that would
have needed to be re-written if that were changed.

In most contexts (including this one) a string literal gets implicitly
converted into a pointer to the first element of that array. It was a
good idea to store that pointer in a 'const char*' object. That way, if
you make the mistake of using s to attempt to modify an element of that
array, it will often be a constraint violation, requiring a diagnostic
that will warn you of that mistake.

The only thing that you can do with 't', that you can't do with 's', is
attempt to modify the thing it points at without it being a constraint
violation. However, the behavior would still be undefined, which is
precisely why assigning the value of 's' to 't' is a constraint
violation. Adding the cast silences the mandatory diagnostic - but it
doesn't remove the danger that the diagnostic would have warned you about.

That is an example of why using a cast is almost always dangerous, and
so should be avoided when possible (but not by writing code with
undefined behavior, like your misuse of va_arg() above). A cast tells
the compiler: "Don't worry about the possible problems. I know what I'm
doing - this is one of the rare cases where it is actually necessary".
Based upon the multiple misunderstandings shown in your message,
you most certainly don't know what you're doing.
-- 
James Kuyper

Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Few questions about casting away const. Daniel <daniel@inventati.org> - 2014-03-04 11:18 +0000
  Re: Few questions about casting away const. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-04 12:39 +0000
  Re: Few questions about casting away const. Kaz Kylheku <kaz@kylheku.com> - 2014-03-04 17:05 +0000
  Re: Few questions about casting away const. Keith Thompson <kst-u@mib.org> - 2014-03-04 10:16 -0800
    Re: Few questions about casting away const. Daniel <daniel@inventati.org> - 2014-03-05 03:45 +0000
      Re: Few questions about casting away const. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-05 04:20 +0000
  Re: Few questions about casting away const. James Kuyper <jameskuyper@verizon.net> - 2014-03-04 15:18 -0500
    Re: Few questions about casting away const. Daniel <daniel@inventati.org> - 2014-03-05 04:14 +0000
      Re: Few questions about casting away const. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-05 04:35 +0000
        Re: Few questions about casting away const. Daniel <daniel@inventati.org> - 2014-03-05 06:11 +0000
          Re: Few questions about casting away const. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-05 12:14 +0000
            Re: Few questions about casting away const. Daniel Harrison <daniel@inventati.org> - 2014-03-07 04:31 +0000
              Re: Few questions about casting away const. Barry Schwarz <schwarzb@dqel.com> - 2014-03-06 21:23 -0800
                Re: Few questions about casting away const. Kaz Kylheku <kaz@kylheku.com> - 2014-03-07 05:59 +0000
              Re: Few questions about casting away const. James Kuyper <jameskuyper@verizon.net> - 2014-03-07 07:18 -0500
              Re: Few questions about casting away const. Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-10 00:30 -0700
                Re: Few questions about casting away const. Keith Thompson <kst-u@mib.org> - 2014-03-10 09:00 -0700
                Re: Few questions about casting away const. Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-10 11:13 -0700
                Re: Few questions about casting away const. Keith Thompson <kst-u@mib.org> - 2014-03-10 12:10 -0700
                Re: Few questions about casting away const. Kaz Kylheku <kaz@kylheku.com> - 2014-03-11 07:38 +0000
                Re: Few questions about casting away const. Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 09:02 -0700
          Re: Few questions about casting away const. Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-10 02:29 -0700
            Re: Few questions about casting away const. Keith Thompson <kst-u@mib.org> - 2014-03-10 10:52 -0700
              Re: Few questions about casting away const. Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 08:50 -0700

csiph-web