Velocity Reviews - Computer Hardware Reviews

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

Reply
Thread Tools

const type question

 
 
herrcho
Guest
Posts: n/a
 
      10-03-2003
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 ?

i can't get the meaning of const when used in parameter..

Thanks in advance ~
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      10-03-2003
"herrcho" <> 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 ?


Nothing, since you're not trying to change anything anyway.

> i can't get the meaning of const when used in parameter..


If a parameter is declared const, the function cannot change it. This
sounds like it's no change, since a function cannot change a the value
of a parameter in the caller anyway. However, if the parameter is const,
the function cannot even change its value _within the function_.
If a parameter is a pointer to a const type, the function cannot change
the object the pointer points at.

If you don't modify anything in the function to begin with, this doesn't
matter, of course. However, the above looks like a comparison function
for qsort() (or bsearch()). In that case, the consts are there to
prevent you from changing the objects behind qsort()'s back, since doing
so could mess up the sorting algorithm.

Richard
 
Reply With Quote
 
 
 
 
Simon Biber
Guest
Posts: n/a
 
      10-03-2003
"herrcho" <> 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;
}

That way you will get a diagnostic message from the compiler if
you accidentally attempt to modify the contents of the memory.

--
Simon.


 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      10-03-2003
Simon Biber wrote:
>

.... snip ...
>
> 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;
> }
>
> That way you will get a diagnostic message from the compiler if
> you accidentally attempt to modify the contents of the memory.


Totally agree, EXCEPT for the actual comparison in your example,
which is liable to problems from integer overflow. This is a good
place for:

return (*a > *b) - (*a < *b);

--
Chuck F () ()
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


 
Reply With Quote
 
Simon Biber
Guest
Posts: n/a
 
      10-03-2003
"CBFalconer" <> wrote:
> Simon Biber wrote:
> > int intcmp(const void *va, const void *vb)
> > {
> > const int *a = va, *b = vb;
> > return *a - *b;
> > }
> >
> > That way you will get a diagnostic message from the compiler if
> > you accidentally attempt to modify the contents of the memory.

>
> Totally agree, EXCEPT for the actual comparison in your example,
> which is liable to problems from integer overflow. This is a good
> place for:
>
> return (*a > *b) - (*a < *b);


Yes, my mistake. In fact I usually write it like the equivalent:
return (*a < *b) ? -1 : (*a > *b);

But I prefer your subtraction form, because in the rather arbitrary
and unjustified model of code microefficiency in my head, a subtract
is faster than a compare. This may or may not be true on any of the
platforms I compile for, I wouldn't know.

--
Simon.


 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      10-04-2003
"Simon Biber" <> wrote in message
news:3f7d8e5d$0$26924$ u...
> You can in fact write any
> qsort compare function in a completely typesafe manner


How? The function itself can never guarantee that it won't be applied to a
type that differs from the intended one.

> with no casts, which is much cleaner code:


Cleaner perhaps, but an absense of casts is not typesafety.

--
Peter


 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      10-04-2003
Simon Biber wrote:
>
> "CBFalconer" <> wrote:
> > Simon Biber wrote:
> > > int intcmp(const void *va, const void *vb)
> > > {
> > > const int *a = va, *b = vb;
> > > return *a - *b;
> > > }
> > >
> > > That way you will get a diagnostic message from the compiler if
> > > you accidentally attempt to modify the contents of the memory.

> >
> > Totally agree, EXCEPT for the actual comparison in your example,
> > which is liable to problems from integer overflow. This is a good
> > place for:
> >
> > return (*a > *b) - (*a < *b);

>
> Yes, my mistake. In fact I usually write it like the equivalent:
> return (*a < *b) ? -1 : (*a > *b);
>
> But I prefer your subtraction form, because in the rather arbitrary
> and unjustified model of code microefficiency in my head, a subtract
> is faster than a compare. This may or may not be true on any of the
> platforms I compile for, I wouldn't know.


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

--
pete
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      10-04-2003
pete wrote:
> Simon Biber wrote:
> > "CBFalconer" <> wrote:
> > > Simon Biber wrote:

> >
> > > > int intcmp(const void *va, const void *vb)
> > > > {
> > > > const int *a = va, *b = vb;
> > > > return *a - *b;
> > > > }
> > > >
> > > > That way you will get a diagnostic message from the compiler if
> > > > you accidentally attempt to modify the contents of the memory.
> > >
> > > Totally agree, EXCEPT for the actual comparison in your example,
> > > which is liable to problems from integer overflow. This is a good
> > > place for:
> > >
> > > return (*a > *b) - (*a < *b);

> >
> > Yes, my mistake. In fact I usually write it like the equivalent:
> > return (*a < *b) ? -1 : (*a > *b);
> >
> > But I prefer your subtraction form, because in the rather arbitrary
> > and unjustified model of code microefficiency in my head, a subtract
> > is faster than a compare. This may or may not be true on any of the
> > platforms I compile for, I wouldn't know.

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


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.

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.

--
Chuck F () ()
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      10-04-2003
CBFalconer wrote:
>
> pete wrote:
> > Simon Biber wrote:
> > > "CBFalconer" <> wrote:
> > > > Simon Biber wrote:
> > >
> > > > > int intcmp(const void *va, const void *vb)
> > > > > {
> > > > > const int *a = va, *b = vb;
> > > > > return *a - *b;
> > > > > }
> > > > >
> > > > > That way you will get a diagnostic message from the compiler if
> > > > > you accidentally attempt to modify the contents of the memory.
> > > >
> > > > Totally agree, EXCEPT for the actual comparison in your example,
> > > > which is liable to problems from integer overflow. This is a good
> > > > place for:
> > > >
> > > > return (*a > *b) - (*a < *b);
> > >
> > > Yes, my mistake. In fact I usually write it like the equivalent:
> > > return (*a < *b) ? -1 : (*a > *b);
> > >
> > > But I prefer your subtraction form,
> > > because in the rather arbitrary
> > > and unjustified model of code microefficiency in my head,
> > > a subtract is faster than a compare.
> > > This may or may not be true on any of the
> > > platforms I compile for, I wouldn't know.

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

>
> 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.
>
> 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.


Thank you.

--
pete
 
Reply With Quote
 
dam_fool_2003@yahoo.com
Guest
Posts: n/a
 
      10-04-2003
"Simon Biber" <> wrote in message news:<3f7d8e5d$0$26924$. au>...
> "herrcho" <> 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):

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
 
 
 
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
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57