Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   casting const away (http://www.velocityreviews.com/forums/t741571-casting-const-away.html)

copx 01-06-2011 05:47 AM

casting const away
 
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..





copx 01-06-2011 10:20 AM

Re: casting const away
 


"copx" wrote in message news:ig3l22$3hb$1@speranza.aioe.org...
>[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!

Ian Collins 01-06-2011 10:28 AM

Re: casting const away
 
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

copx 01-06-2011 10:33 AM

Re: casting const away
 


"Ian Collins" wrote in message news:8oljqeFni5U11@mid.individual.net...

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

copx 01-06-2011 10:53 AM

Re: casting const away
 


"copx" wrote in message news:ig3l22$3hb$1@speranza.aioe.org...
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.






Ike Naar 01-06-2011 12:55 PM

Re: casting const away
 
On 2011-01-06, copx <copx@gazeta.pl> 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.

lawrence.jones@siemens.com 01-06-2011 05:15 PM

Re: casting const away
 
copx <copx@gazeta.pl> 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

copx 01-06-2011 09:43 PM

Re: casting const away
 


"Ike Naar" wrote in message
news:slrn3vfsiibeu5.aj4.ike@iceland.freeshell.org. ..
>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.



Ian Collins 01-06-2011 10:04 PM

Re: casting const away
 
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

sandeep 01-06-2011 10:11 PM

Re: casting const away
 
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.


All times are GMT. The time now is 04:02 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.