Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > const type question

Reply
Thread Tools

const type question

 
 
j
Guest
Posts: n/a
 
      10-04-2003

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) m...
> "Simon Biber" <(E-Mail Removed)> wrote in message

news:<3f7d8e5d$0$26924$(E-Mail Removed). au>...
> > "herrcho" <(E-Mail Removed)> wrote:
> > > int intcmp(const void *a, const void *b)
> > > {
> > > return (*(int*)a - *(int*)b);
> > > }
> > >
> > > in the above , if i put just 'void' instead of 'const void' as a
> > > parameter,
> > >
> > > what's the difference ?

> >
> > If you're intending to pass this function to qsort or something
> > that expects a parameter of type int(*)(const void*,const void*)
> > then you must not change from const void to void, this will be
> > a constraint violation (wrong type of argument) or else undefined
> > behaviour (if you say cast it back to the right type).
> >
> > > i can't get the meaning of const when used in parameter..

> >
> > When used as 'const type *a' it means that you are not allowed to
> > modify the thing that the pointer is pointing to. Unfortunately
> > due to the bad way you wrote the function this protection is lost
> > when you cast the argument to (int*). You can in fact write any
> > qsort compare function in a completely typesafe manner with no
> > casts, which is much cleaner code:
> >
> > int intcmp(const void *va, const void *vb)
> > {
> > const int *a = va, *b = vb;
> > return *a - *b;
> > }
> >

> Friends,
> Don't we have to cast a void* so that the void points to a valid
> value (as per 6.3.2.3 of the standard). (Correct me if I am wrong):
>


No, this isn't C++.

The standard states that:
``A pointer to void may be converted to or from a pointer to any incomplete
or object
type. A pointer to any incomplete or object type may be converted to a
pointer to void
and back again; the result shall compare equal to the original pointer.''


And for simple assignment(which also applies to initialization) that:
``One operand is a pointer to an object or incomplete type and the other
is a pointer to a qualified or unqualified version of void, and the type
pointed to by the left has all the qualifiers of the type pointed to by
the right''

Which makes casting in this case entirely unnecessary.

example.c:
#include <stdio.h>
int main(void)
{
unsigned int i;
unsigned int *p;
void *p1;

p = &i;
p1 = p;
p = p1;

if(p == p1)
puts("They compare equal.");
else
puts("Get a new compiler.");

return 0;
}


> int fun(const void *a, const void *b)
> {
> unsigned int *p , *q;
> p =(unsigned int*) a, q =(unsigned int*) b;
> /*return (*p > *q ) - (*p < *q); */
> return *p - *q;
> }
> int main(void)
> {
> int a=2,b=2,c=8,d=6;
> printf("%d %d\n",fun(&a,&b),fun(&c,&d));
> return 0;
> }
>
> OUTPUT:
>
> 0 2
>
> And for the second one:
>
> int fun(const void *a, const void *b)
> {
> unsigned int *p , *q;
> p =(unsigned int*) a, q =(unsigned int*) b;
> return (*p > *q ) - (*p < *q);
> /*return *p - *q; */
> }
> int main(void)
> {
> int a=2,b=2,c=8,d=6;
> printf("%d %d\n",fun(&a,&b),fun(&c,&d));
> return 0;
> }
>
> OUTPUT:
> 0 1
>
> Is there any UB?
>
>
>
>
> > That way you will get a diagnostic message from the compiler if
> > you accidentally attempt to modify the contents of the memory.



 
Reply With Quote
 
 
 
 
dam_fool_2003@yahoo.com
Guest
Posts: n/a
 
      10-05-2003
"j" <(E-Mail Removed)> wrote in message news:<_oCfb.16185$(E-Mail Removed)>. ..
> <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) m...
> > "Simon Biber" <(E-Mail Removed)> wrote in message

> news:<3f7d8e5d$0$26924$(E-Mail Removed). au>...
> > > "herrcho" <(E-Mail Removed)> wrote:
> > > > int intcmp(const void *a, const void *b)
> > > > {
> > > > return (*(int*)a - *(int*)b);
> > > > }
> > > >
> > > > in the above , if i put just 'void' instead of 'const void' as a
> > > > parameter,
> > > >
> > > > what's the difference ?
> > >
> > > If you're intending to pass this function to qsort or something
> > > that expects a parameter of type int(*)(const void*,const void*)
> > > then you must not change from const void to void, this will be
> > > a constraint violation (wrong type of argument) or else undefined
> > > behaviour (if you say cast it back to the right type).
> > >
> > > > i can't get the meaning of const when used in parameter..
> > >
> > > When used as 'const type *a' it means that you are not allowed to
> > > modify the thing that the pointer is pointing to. Unfortunately
> > > due to the bad way you wrote the function this protection is lost
> > > when you cast the argument to (int*). You can in fact write any
> > > qsort compare function in a completely typesafe manner with no
> > > casts, which is much cleaner code:
> > >
> > > int intcmp(const void *va, const void *vb)
> > > {
> > > const int *a = va, *b = vb;
> > > return *a - *b;
> > > }
> > >

> > Friends,
> > Don't we have to cast a void* so that the void points to a valid
> > value (as per 6.3.2.3 of the standard). (Correct me if I am wrong):
> >

>
> No, this isn't C++.


I don't have C++ standard.I have the slandered ISO-C-1999-04, which
has got the same words as you mentioned.

> The standard states that:
> ``A pointer to void may be converted to or from a pointer to any incomplete
> or object
> type. A pointer to any incomplete or object type may be converted to a
> pointer to void
> and back again; the result shall compare equal to the original pointer.''
>
>
> And for simple assignment(which also applies to initialization) that:
> ``One operand is a pointer to an object or incomplete type and the other
> is a pointer to a qualified or unqualified version of void, and the type
> pointed to by the left has all the qualifiers of the type pointed to by
> the right''
>
> Which makes casting in this case entirely unnecessary.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^
No, not in the above case with const void* in the parameter and
non-const with in the function scope.
>
> example.c:
> #include <stdio.h>
> int main(void)
> {
> unsigned int i;
> unsigned int *p;
> void *p1;
>
> p = &i;
> p1 = p;
> p = p1;
>
> if(p == p1)
> puts("They compare equal.");
> else
> puts("Get a new compiler.");
>
> return 0;
> }
>
>
> > int fun(const void *a, const void *b)
> > {
> > unsigned int *p , *q;
> > p =(unsigned int*) a, q =(unsigned int*) b;
> > /*return (*p > *q ) - (*p < *q); */
> > return *p - *q;
> > }
> > int main(void)
> > {
> > int a=2,b=2,c=8,d=6;
> > printf("%d %d\n",fun(&a,&b),fun(&c,&d));
> > return 0;
> > }
> >
> > OUTPUT:
> >
> > 0 2
> >
> > And for the second one:
> >
> > int fun(const void *a, const void *b)
> > {
> > unsigned int *p , *q;
> > p =(unsigned int*) a, q =(unsigned int*) b;
> > return (*p > *q ) - (*p < *q);
> > /*return *p - *q; */
> > }
> > int main(void)
> > {
> > int a=2,b=2,c=8,d=6;
> > printf("%d %d\n",fun(&a,&b),fun(&c,&d));
> > return 0;
> > }
> >
> > OUTPUT:
> > 0 1
> >
> > Is there any UB?
> >
> >
> >
> >
> > > That way you will get a diagnostic message from the compiler if
> > > you accidentally attempt to modify the contents of the memory.

 
Reply With Quote
 
 
 
 
j
Guest
Posts: n/a
 
      10-05-2003

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> "j" <(E-Mail Removed)> wrote in message

news:<_oCfb.16185$(E-Mail Removed)>. ..
> > <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed) m...
> > > "Simon Biber" <(E-Mail Removed)> wrote in message

> > news:<3f7d8e5d$0$26924$(E-Mail Removed). au>...
> > > > "herrcho" <(E-Mail Removed)> wrote:
> > > > > int intcmp(const void *a, const void *b)
> > > > > {
> > > > > return (*(int*)a - *(int*)b);
> > > > > }
> > > > >
> > > > > in the above , if i put just 'void' instead of 'const void' as a
> > > > > parameter,
> > > > >
> > > > > what's the difference ?
> > > >
> > > > If you're intending to pass this function to qsort or something
> > > > that expects a parameter of type int(*)(const void*,const void*)
> > > > then you must not change from const void to void, this will be
> > > > a constraint violation (wrong type of argument) or else undefined
> > > > behaviour (if you say cast it back to the right type).
> > > >
> > > > > i can't get the meaning of const when used in parameter..
> > > >
> > > > When used as 'const type *a' it means that you are not allowed to
> > > > modify the thing that the pointer is pointing to. Unfortunately
> > > > due to the bad way you wrote the function this protection is lost
> > > > when you cast the argument to (int*). You can in fact write any
> > > > qsort compare function in a completely typesafe manner with no
> > > > casts, which is much cleaner code:
> > > >
> > > > int intcmp(const void *va, const void *vb)
> > > > {
> > > > const int *a = va, *b = vb;
> > > > return *a - *b;
> > > > }
> > > >
> > > Friends,
> > > Don't we have to cast a void* so that the void points to a valid
> > > value (as per 6.3.2.3 of the standard). (Correct me if I am wrong):
> > >

> >
> > No, this isn't C++.

>
> I don't have C++ standard.I have the slandered ISO-C-1999-04, which
> has got the same words as you mentioned.
>
> > The standard states that:
> > ``A pointer to void may be converted to or from a pointer to any

incomplete
> > or object
> > type. A pointer to any incomplete or object type may be converted to a
> > pointer to void
> > and back again; the result shall compare equal to the original

pointer.''
> >
> >
> > And for simple assignment(which also applies to initialization) that:
> > ``One operand is a pointer to an object or incomplete type and the other
> > is a pointer to a qualified or unqualified version of void, and the type
> > pointed to by the left has all the qualifiers of the type pointed to by
> > the right''
> >
> > Which makes casting in this case entirely unnecessary.

> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^
> No, not in the above case with const void* in the parameter and
> non-const with in the function scope.
> >


Where is the type in the ``intcmp'' function which is not qualified by
const?
I can see two pointer to ints qualified by const being initialized with two
pointers to void which are also qualified by const.

> > example.c:
> > #include <stdio.h>
> > int main(void)
> > {
> > unsigned int i;
> > unsigned int *p;
> > void *p1;
> >
> > p = &i;
> > p1 = p;
> > p = p1;
> >
> > if(p == p1)
> > puts("They compare equal.");
> > else
> > puts("Get a new compiler.");
> >
> > return 0;
> > }
> >
> >
> > > int fun(const void *a, const void *b)
> > > {
> > > unsigned int *p , *q;
> > > p =(unsigned int*) a, q =(unsigned int*) b;
> > > /*return (*p > *q ) - (*p < *q); */
> > > return *p - *q;
> > > }
> > > int main(void)
> > > {
> > > int a=2,b=2,c=8,d=6;
> > > printf("%d %d\n",fun(&a,&b),fun(&c,&d));
> > > return 0;
> > > }
> > >
> > > OUTPUT:
> > >
> > > 0 2
> > >
> > > And for the second one:
> > >
> > > int fun(const void *a, const void *b)
> > > {
> > > unsigned int *p , *q;
> > > p =(unsigned int*) a, q =(unsigned int*) b;
> > > return (*p > *q ) - (*p < *q);
> > > /*return *p - *q; */
> > > }
> > > int main(void)
> > > {
> > > int a=2,b=2,c=8,d=6;
> > > printf("%d %d\n",fun(&a,&b),fun(&c,&d));
> > > return 0;
> > > }
> > >
> > > OUTPUT:
> > > 0 1
> > >
> > > Is there any UB?
> > >
> > >
> > >
> > >
> > > > That way you will get a diagnostic message from the compiler if
> > > > you accidentally attempt to modify the contents of the memory.



 
Reply With Quote
 
Kevin Bracey
Guest
Posts: n/a
 
      10-07-2003
In message <(E-Mail Removed)>
CBFalconer <(E-Mail Removed)> wrote:

> pete wrote:
> > > > return (*a > *b) - (*a < *b);
> > > return (*a < *b) ? -1 : (*a > *b);

> >
> > I see two unconditional comparisons and a subtraction in the first,
> > but only two comparisons, with one of them being conditional,
> > in the second.


Actually, both cases will probably only need to have one actual comparison on
most architectures, with a multi-way set of conditions following.

> However the emitted code will often not have any jumps in it (for
> the first), which avoids flushing any instruction queues. I
> learned it from someone, and consider it a trick worth knowing.


Isn't micro-optimisation great?

> The point is that they are both safe, and have a chance to
> simultaneously be efficient and clear. However there may be
> considerable code involved in converting a machine comparison into
> the 0 or 1 representation, in which case the ?: coding will be
> superior.


Also, conditional execution (as found in the ARM) tends to render such jump
avoidance counter-productive, as there are unlikely to be any branches
involved in such a simple condition. The subtraction comes out as the
tedious:

intcmp
LDR a1,[a1]
LDR a2,[a2]
CMP a1,a2
MOVLE a1,#0
MOVGT a1,#1
MOVGE a2,#0
MOVLT a2,#1
SUB a1,a1,a2
MOV pc,lr

Whereas the ? : form wins by 1-4 cycles:

intcmp
LDR a1,[a1]
LDR a2,[a2]
CMP a1,a2
MVNLT a1,#0
MOVLT pc,lr
MOVLE a1,#0
MOVGT a1,#1
MOV pc,lr

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1223 503458
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.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
Constant qualifier pros/cons, type const& versus const type&, etc. paulo C++ 9 03-06-2009 09:55 AM
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 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
const type& and type const& p|OtrEk C++ 6 07-17-2005 06:36 PM



Advertisments