Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Defeating Optimisation for memcmp()

Reply
Thread Tools

Defeating Optimisation for memcmp()

 
 
Martin
Guest
Posts: n/a
 
      11-20-2007
My apologies - I had meant to submit a thank-you message to all your
responses before now.

So, thanks for the helpful advice.

I have two related questions. According to K&R2:

"Except that it should diagnose explicit attempts to change 'const'
objects, a compiler may ignore these qualifiers."

"These qualifiers" are 'const' and 'volatile'. It seems that this could be
an issue. I can carefully implement Eric Sosman's suggestion regarding using
a volatile pointer to the structure, but it seems an ANSI/ISO conformant
compiler is free to ignore it, and the compiler then could optimise away the
following memcmp(). Could someone clarify this for me?

Also, along those lines of making a pointer volatile, I would like some
clarification. Consider this code abstract:

volatile char arr[10];
char arr2[10]
/* ... code that initialises both arrays ... */
if ( memcmp(&arr[3], &arr2[3], 1) ... )
/* etc. */

Does the deferencing of the first argument, arr, mean that memcmp is being
handed a non-volatile type (which is, I believe, the principle behind Chris
Torek's suggestion)?

--
Martin



 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      11-20-2007
Martin wrote On 11/20/07 13:52,:
> My apologies - I had meant to submit a thank-you message to all your
> responses before now.
>
> So, thanks for the helpful advice.
>
> I have two related questions. According to K&R2:
>
> "Except that it should diagnose explicit attempts to change 'const'
> objects, a compiler may ignore these qualifiers."
>
> "These qualifiers" are 'const' and 'volatile'. It seems that this could be
> an issue. I can carefully implement Eric Sosman's suggestion regarding using
> a volatile pointer to the structure, but it seems an ANSI/ISO conformant
> compiler is free to ignore it, and the compiler then could optimise away the
> following memcmp(). Could someone clarify this for me?


(1) The compiler can ignore volatile only by resorting
to an obstructionist interpretation of the "what constitutes
an access is implementation-defined" clause. Such a compiler
is not trying to be useful in its target environment, and
will find few adopters. If you've got a compiler that's
actually trying to support your environment, it will do the
Right Thing with volatile -- all you need to worry about is
the precise, implementation-defined nature of "Right."

(2) It's still an error to pass a pointer to a volatile
object to a function that's not expecting it. Not a problem
of optimization, but an error on the programmer's part.

> Also, along those lines of making a pointer volatile, I would like some
> clarification. Consider this code abstract:
>
> volatile char arr[10];
> char arr2[10]
> /* ... code that initialises both arrays ... */
> if ( memcmp(&arr[3], &arr2[3], 1) ... )
> /* etc. */
>
> Does the deferencing of the first argument, arr, mean that memcmp is being
> handed a non-volatile type (which is, I believe, the principle behind Chris
> Torek's suggestion)?


Looks like an error to me. Internally, memcmp() doesn't
"know" it's dealing with volatile characters, so it won't
necessarily "access" them in the right order or the right
way. (For example, it may discover that it can fetch them
four at a time or eight at a time, completely unaware that
the "off-the-end" read might tickle a nearby volatile object
that you weren't expecting it to touch. Your fault, not
memcmp()'s.)

The straightforward `if (arr[3] != arr2[3]) ...' says
what you intend, says it correctly, and works (barring an
intentionally obstreporous compiler).

--
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      11-20-2007
"Martin" <martin.o_brien@[no-spam]which.net> writes:

> I have two related questions. According to K&R2:
>
> "Except that it should diagnose explicit attempts to change 'const'
> objects, a compiler may ignore these qualifiers."


This statement is given in the context of qualifiers on types,
not qualifiers on pointers. I think that this is intended to
mean that the compiler is not obligated to store const objects in
read-only memory, and that it is not obligated to put volatile
objects in a special section of memory either.
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
Martin
Guest
Posts: n/a
 
      11-20-2007

"Eric Sosman" <(E-Mail Removed)> wrote in message
news:1195591111.496032@news1nwk...
> Looks like an error to me. Internally, memcmp() doesn't
> "know" it's dealing with volatile characters, so it won't
> necessarily "access" them in the right order or the right
> way. (For example, it may discover that it can fetch them
> four at a time or eight at a time, completely unaware that
> the "off-the-end" read might tickle a nearby volatile object
> that you weren't expecting it to touch. Your fault, not
> memcmp()'s.)


I think my example was wrong. Of course memcpy() is being passed a pointer
to a volatile char. This is more what I meant:

char arr[10];
char arr2[10]
volatile char *parr = arr;
/* ... code that initialises both arrays ... */
if ( memcmp(&parr[3], &arr2[3], 1) ... )
/* etc. */

Which is analagous to Chris Torek's use of the volatile pointer to
structure. I think that is OK because the first argument now is not pointing
to a volatile once deferenced, but the parr itself it volatile so the call
to memcmp() cannot be optimised away - *however* in the case above where one
element of an array is being compared with another, I can see that my
original example in tandem with the use of the != operator you suggest is a
solution I can adopt.

Thanks for your help.

--
Martin



 
Reply With Quote
 
Martin
Guest
Posts: n/a
 
      11-20-2007
"Ben Pfaff" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "Martin" <martin.o_brien@[no-spam]which.net> writes:
>
>> I have two related questions. According to K&R2:
>>
>> "Except that it should diagnose explicit attempts to change 'const'
>> objects, a compiler may ignore these qualifiers."

>
> This statement is given in the context of qualifiers on types,
> not qualifiers on pointers. I think that this is intended to
> mean that the compiler is not obligated to store const objects in
> read-only memory, and that it is not obligated to put volatile
> objects in a special section of memory either.


Are you saying that the quote from K&R2 above does not apply in these
instances?

int i, *const cpi = &i;
const int *pci;

--
Martin



 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      11-21-2007
"Martin" <martin.o_brien@[no-spam]which.net> writes:

> "Ben Pfaff" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> "Martin" <martin.o_brien@[no-spam]which.net> writes:
>>
>>> I have two related questions. According to K&R2:
>>>
>>> "Except that it should diagnose explicit attempts to change 'const'
>>> objects, a compiler may ignore these qualifiers."

>>
>> This statement is given in the context of qualifiers on types,
>> not qualifiers on pointers. I think that this is intended to
>> mean that the compiler is not obligated to store const objects in
>> read-only memory, and that it is not obligated to put volatile
>> objects in a special section of memory either.

>
> Are you saying that the quote from K&R2 above does not apply in these
> instances?
>
> int i, *const cpi = &i;


cpi is a const pointer to a non-const int. The compiler is not
obligated to put cpi into a read-only section.

> const int *pci;


pci is a non-const pointer to a const int. The compiler may not
put pci into a read-only section.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1utchar(a[i&15]);break;}}}
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      11-21-2007
"Martin" <martin.o_brien@[no-spam]which.net> writes:

> "Eric Sosman" <(E-Mail Removed)> wrote in message
> news:1195591111.496032@news1nwk...
>> Looks like an error to me. Internally, memcmp() doesn't
>> "know" it's dealing with volatile characters, so it won't
>> necessarily "access" them in the right order or the right
>> way. (For example, it may discover that it can fetch them
>> four at a time or eight at a time, completely unaware that
>> the "off-the-end" read might tickle a nearby volatile object
>> that you weren't expecting it to touch. Your fault, not
>> memcmp()'s.)

>
> I think my example was wrong. Of course memcpy() is being passed a pointer
> to a volatile char. This is more what I meant:
>
> char arr[10];
> char arr2[10]
> volatile char *parr = arr;
> /* ... code that initialises both arrays ... */
> if ( memcmp(&parr[3], &arr2[3], 1) ... )
> /* etc. */


You haven't changed anything as far as the constraint violation on the
call to memcmp is concerned. Both

volatile char x[10];
memcmp(x, ...);
memcmp(&x[3], ...);

and

volatile char *x;
memcmp(x, ...);
memcmp(&x[3], ...);

all pass a 'char pointer to volatile' where 'void pointer to const' is
expected.

--
Ben.
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      11-21-2007
Ben Pfaff wrote:
> "Martin" <martin.o_brien@[no-spam]which.net> writes:
>
>> I have two related questions. According to K&R2:
>>
>> "Except that it should diagnose explicit attempts to change
>> 'const' objects, a compiler may ignore these qualifiers."

>
> This statement is given in the context of qualifiers on types,
> not qualifiers on pointers. I think that this is intended to
> mean that the compiler is not obligated to store const objects
> in read-only memory, and that it is not obligated to put
> volatile objects in a special section of memory either.


The following was my attempt to test incrementing of a void*. I
think I can imagine situations where this ability would be useful
to bypass pointer incrementation. BTW, cc is shorthand for:
gcc -W -Wall -ansi -pedantic
and accesses gcc 3.2.1.

[1] c:\c\junk>cat junk.c
#include <stdio.h>

int main(void) {
void *p, *pb;
char by;

p = &by;

pb = p++;
if (pb == p) puts("++ uses sizeof void* == 0");
else puts("No luck here");
return 0;
}

[1] c:\c\junk>cc junk.c
junk.c: In function `main':
junk.c:9: warning: wrong type argument to increment

[1] c:\c\junk>a
No luck here

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      11-21-2007
CBFalconer <(E-Mail Removed)> writes:

> Ben Pfaff wrote:
>> "Martin" <martin.o_brien@[no-spam]which.net> writes:
>>
>>> I have two related questions. According to K&R2:
>>>
>>> "Except that it should diagnose explicit attempts to change
>>> 'const' objects, a compiler may ignore these qualifiers."

>>
>> This statement is given in the context of qualifiers on types,
>> not qualifiers on pointers. I think that this is intended to
>> mean that the compiler is not obligated to store const objects
>> in read-only memory, and that it is not obligated to put
>> volatile objects in a special section of memory either.

>
> The following was my attempt to test incrementing of a void*. I
> think I can imagine situations where this ability would be useful
> to bypass pointer incrementation. [...]


I am struggling to understand how this is anything but a non
sequitur. Can you explain?
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
Dann Corbit
Guest
Posts: n/a
 
      11-21-2007

"Ben Pfaff" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> CBFalconer <(E-Mail Removed)> writes:
>
>> Ben Pfaff wrote:
>>> "Martin" <martin.o_brien@[no-spam]which.net> writes:
>>>
>>>> I have two related questions. According to K&R2:
>>>>
>>>> "Except that it should diagnose explicit attempts to change
>>>> 'const' objects, a compiler may ignore these qualifiers."
>>>
>>> This statement is given in the context of qualifiers on types,
>>> not qualifiers on pointers. I think that this is intended to
>>> mean that the compiler is not obligated to store const objects
>>> in read-only memory, and that it is not obligated to put
>>> volatile objects in a special section of memory either.

>>
>> The following was my attempt to test incrementing of a void*. I
>> think I can imagine situations where this ability would be useful
>> to bypass pointer incrementation. [...]

>
> I am struggling to understand how this is anything but a non
> sequitur. Can you explain?


A void pointer has no stride and cannot be incremented. I find the sentence
very difficult to parse.



--
Posted via a free Usenet account from http://www.teranews.com

 
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
Defeating default host William W. Plummer Firefox 2 07-22-2004 12:46 PM
Defeating pop-up stoppers? Bill Java 10 01-03-2004 04:37 PM
Defeating Pop-up stoppers please? Bill Java 23 11-21-2003 10:15 AM
Defeating Pop-up stoppers please? Bill HTML 71 11-14-2003 09:12 PM
Defeating Popup Stoppers Bill Java 6 11-07-2003 01:56 PM



Advertisments