Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > casting const away

Reply
Thread Tools

casting const away

 
 
copx
Guest
Posts: n/a
 
      01-06-2011
In a situation like this

void my_func(const FOO_T *);

*foo = 'b';
my_func(foo);
putchar(*foo);

Is the compiler allowed to replace the second foo->a with 'b'
i.e. allowed to assume that my_func does indeed not modify
foo? I mean in C you one cast "const" away within said function.
I wrote a test program who did just that, compiled with GCC
-Wall -Wextra -ansi -pedantic -O3 : not even a warning and
the compiler did not optimize the dereference away..




 
Reply With Quote
 
 
 
 
copx
Guest
Posts: n/a
 
      01-06-2011


"copx" wrote in message news:ig3l22$3hb$...
>[snip]
>Is the compiler allowed to replace the second foo->a with 'b'
>i.e. allowed to assume that my_func does indeed not modify
>foo? I mean in C you one cast "const" away within said function.
>I wrote a test program who did just that, compiled with GCC
>-Wall -Wextra -ansi -pedantic -O3 : not even a warning and
>the compiler did not optimize the dereference away..


Wow, clc isn't what it used to be. In the good ol' days these
group was so full of people who had memorized the C standard
like Grand Ayatollahs the Quran that such a simple standard
question was usually answered within minutes.

Whatever, so I grabbed a draft copy of the standard and
tried to figure it out myself. These documents really aren't
written with end-users in mind, I tell you. However, after
10 minutes or so I arrived at the conclusion that this works
and is guranteed to work because "const" is only really
meaningful when it's applied to the "object" itself. I.e. a const
pointer to something doesn't actually tell the compiler
that the object pointed to is constant, this type of "constness"
only exist to produce compiler warnings which may aid
the programmer. By expliticly casting to a non-const
pointer I get no warning because removing the "const" from
the pointer just means.. telling the compiler not to
produce a warning!
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      01-06-2011
On 01/ 6/11 06:47 PM, copx wrote:
> In a situation like this
>
> void my_func(const FOO_T *);
>
> *foo = 'b';
> my_func(foo);
> putchar(*foo);
>
> Is the compiler allowed to replace the second foo->a with 'b'


What second foo->a? You haven't shown a first, let alone a second.
Without code your post does not make sense.

--
Ian Collins
 
Reply With Quote
 
copx
Guest
Posts: n/a
 
      01-06-2011


"Ian Collins" wrote in message news:...

On 01/ 6/11 06:47 PM, copx wrote:
>> In a situation like this
>>
>> void my_func(const FOO_T *);
>>
>> *foo = 'b';
>> my_func(foo);
>> putchar(*foo);
>>
>> Is the compiler allowed to replace the second foo->a with 'b'

>
>What second foo->a? You haven't shown a first, let alone a second.
>Without code your post does not make sense.


Oops, I simplified the code after writing the text below and forgot
to update the text to reflect the change. "Second foo->a" should
"Second *foo".





--
Ian Collins
 
Reply With Quote
 
copx
Guest
Posts: n/a
 
      01-06-2011


"copx" wrote in message news:ig3l22$3hb$...
Here's some compile-ready code which illustrates the issue:

#include <stdio.h>

void foo(const int *c)
{
*((int *)c) = 'B';
}


int main(void)
{
int a = 'A';

foo(&a);

putchar(a);

return 0;
}


====
Result: no warnings, prints 'B';

As I wrote in the other post I think I have figured it out
already.





 
Reply With Quote
 
Ike Naar
Guest
Posts: n/a
 
      01-06-2011
On 2011-01-06, copx <> wrote:
> In a situation like this
>
> void my_func(const FOO_T *);
>
> *foo = 'b';
> my_func(foo);
> putchar(*foo);
>
> Is the compiler allowed to replace the second foo->a with 'b'
> i.e. allowed to assume that my_func does indeed not modify
> foo? I mean in C you one cast "const" away within said function.
> I wrote a test program who did just that, compiled with GCC
> -Wall -Wextra -ansi -pedantic -O3 : not even a warning and
> the compiler did not optimize the dereference away..


The code has undefined behaviour.

6.7.3
5 If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with non-const-qualified
type, the behavior is undefined.

The compiler is not obliged to give a warning for undefined behaviour.
 
Reply With Quote
 
lawrence.jones@siemens.com
Guest
Posts: n/a
 
      01-06-2011
copx <> wrote:
>
> Here's some compile-ready code which illustrates the issue:
>
> #include <stdio.h>
>
> void foo(const int *c)
> {
> *((int *)c) = 'B';
> }
>
>
> int main(void)
> {
> int a = 'A';
>
> foo(&a);
> putchar(a);
> return 0;
> }
>
> ====
> Result: no warnings, prints 'B';


It might just as well have printed 'A'. You have lied to the compiler
by declaring that foo() does not modify what its argument points to but
going ahead and doing so anyway. The compiler is permitted to believe
the declaration but is not required to, so either result is acceptable.
The code is not strictly conforming, but does not violate any
constraints so no diagnostics are required. It also does not contain
undefined behavior, just unspecified behavior.
--
Larry Jones

I keep forgetting that rules are only for little nice people. -- Calvin
 
Reply With Quote
 
copx
Guest
Posts: n/a
 
      01-06-2011


"Ike Naar" wrote in message
news:. ..
>The code has undefined behaviour.
>
>6.7.3
>5 If an attempt is made to modify an object defined with a
>const-qualified type through use of an lvalue with non-const-qualified
>type, the behavior is undefined.


I read the same section of the standard and this doesn't support
your statement IMO. The standard talks about OBJECTS with
a const-qualified type NOT about const-qualified references to
non-const-qualified objects. I.e. this only means that modifying a
"const int" is undefined, const-qualified references to
non-const-qualified objects aren't mentioned here.

Digging further I could only find this:
==
const int *ptr_to_constant;
...
The contents of anyobject pointed to by ptr_to_constant shall
not be modified through that pointer,
==

Then I had to reference an entirely different section of the
standard to figure out the technical definition of "shall not".
=====
If a ‘‘shall’’or‘‘shall not’’requirement that appears outside of
a constraint is violated, the behavior is undefined.
===

Ok,case finally solved, right? Unfortunately, no!

The standard only says "through that pointer" notice the "that".
I can copy the value of the const pointer to a non-const pointer
and then use this newly created pointer to modify the object thus
the object is never actually modified "through that pointer".

The exact, literal meaning of what the standard says validates the
behavior of GCC IMO, but the wording of the standard is so horribly
confusing here that I wouldn't be surprised if other compilers interpret
this mess in a different way.


 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      01-06-2011
On 01/ 7/11 10:43 AM, copx wrote:
>
> The standard only says "through that pointer" notice the "that".
> I can copy the value of the const pointer to a non-const pointer
> and then use this newly created pointer to modify the object thus
> the object is never actually modified "through that pointer".


Yes you can, but you have to lie to the compiler (cast) to do so.

> The exact, literal meaning of what the standard says validates the
> behavior of GCC IMO, but the wording of the standard is so horribly
> confusing here that I wouldn't be surprised if other compilers interpret
> this mess in a different way.


The wording is clear: once you lie to the compiler you are in the land
of undefined behaviour.

--
Ian Collins
 
Reply With Quote
 
sandeep
Guest
Posts: n/a
 
      01-06-2011
christian.bau writes:
> Use "const int* restrict" instead:
>
> int i; const int* restrict p = &i; * (int *) p = 1; // Undefined
> behaviour


I don't believe that this will be an undefined behavior because p and
(int*)p are both pointers to the same memory address hence there is no
aliasing here.
 
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
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 PM
const correctness - should C++ prefer const member over non-const? fungus C++ 13 10-31-2008 05:33 AM
Casting from const pair<const unsigned char*, size_t>* to constpair<unsigned char*, size_t>* Alex Vinokur C++ 9 10-13-2008 05:05 PM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM



Advertisments