Hello,
I've come across the following comparison function used as the 4th
parameter in qsort()
int cmp(const void *px, const void *py)
{
const double *x = px, *y = py;
return (*x > *y) - (*x < *y);
}
It came "as-is" i.e. no comments.
Is it good style to write comparison functions that way?
Should the return values be made more explicit? Or would it be enough to
add comments explaining why the function (usually) works?
--
Regards, Spoon 14 5019
Spoon schrieb: Hello,
I've come across the following comparison function used as the 4th parameter in qsort()
int cmp(const void *px, const void *py) { const double *x = px, *y = py; return (*x > *y) - (*x < *y); }
It came "as-is" i.e. no comments.
Is it good style to write comparison functions that way?
Should the return values be made more explicit? Or would it be enough to add comments explaining why the function (usually) works?
Depends. Possible points of view:
1) "Everyone" knows that relational operators in C return either 0
or 1, thus Everyone can figure it out.
2) If it is too complicated for Everyone, then it should be commented.
3) If it has to be explained so that Everyone understands it, then it
should not be written this way -- too clever for its own good.
4) Write the code as explicit and simple as possible:
- modern compilers on host PCs can optimise it better,
- there is no danger of misunderstandin g
5) As 4) but if you found out by measuring that cmp() is a bottleneck,
then try this out as one alternative; use the alternative which is
fastest and comment it clearly and explain why you did what you did.
6) As 5) but consider that probably the problem is using qsort(), as
well; you have indirection and function call overhead. It may be better
to write a dedicated double array sort. This makes the above construct
once more unnecessary. Use a well-tested out-of-the-book/from-the-CD
algorithm.
Which alternative you use depends on the people you work with
and the constraints you work under (coding guidelines etc.).
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
"Spoon" <none> wrote in message
news:44******** *************** @news.free.fr.. . Hello,
I've come across the following comparison function used as the 4th parameter in qsort()
int cmp(const void *px, const void *py) { const double *x = px, *y = py; return (*x > *y) - (*x < *y); }
It came "as-is" i.e. no comments.
Is it good style to write comparison functions that way?
Should the return values be made more explicit? Or would it be enough to add comments explaining why the function (usually) works?
-- Regards, Spoon
It's (almost) never a good style to write ANY function with no comments at
all.
Most software development groups have some sort of coding standards.
Mine require ALL functions to specify what the function is for,
describe all parameters, and describe the return value.
In addition, such show-off coding without explaining why it works
can often lead to trouble later on when someone else with less
expertise tries to modify the code, or port it to a different language
(where, for example, boolean true is not 1).
In the above case, the coding is rather silly.
return (*x - *y);
works just as well, with or without the parentheses,
if the function is used only as a qsort() comparer.
If the answer MUST be -1, 0, or +1 for some reason (like it is used
by in some other comparison that requires that), it should be
documented as such.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project
"Fred Kleinschmidt" <fr************ ******@boeing.c om> writes: "Spoon" <none> wrote in message news:44******** *************** @news.free.fr.. . Hello,
I've come across the following comparison function used as the 4th parameter in qsort()
int cmp(const void *px, const void *py) { const double *x = px, *y = py; return (*x > *y) - (*x < *y); }
It came "as-is" i.e. no comments.
Is it good style to write comparison functions that way?
Should the return values be made more explicit? Or would it be enough to add comments explaining why the function (usually) works?
[snip] In the above case, the coding is rather silly. return (*x - *y); works just as well, with or without the parentheses, if the function is used only as a qsort() comparer.
No, it wouldn't. Consider what happens if the subtraction overflows.
Or, since the operands are of type double, consider *x==0.5, *y==0.25;
the result of the subtraction is 0.25, which yields 0 when
(implicitly) converted to int.
--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Fred Kleinschmidt wrote: "Spoon" <none> wrote in message news:44******** *************** @news.free.fr.. . Hello,
I've come across the following comparison function used as the 4th parameter in qsort()
int cmp(const void *px, const void *py) { const double *x = px, *y = py;
^^^^^^
Note that this is comparing doubles
return (*x > *y) - (*x < *y); }
It came "as-is" i.e. no comments.
Is it good style to write comparison functions that way?
Should the return values be made more explicit? Or would it be enough to add comments explaining why the function (usually) works?
-- Regards, Spoon It's (almost) never a good style to write ANY function with no comments at all. Most software development groups have some sort of coding standards. Mine require ALL functions to specify what the function is for, describe all parameters, and describe the return value.
Agreed.
In addition, such show-off coding without explaining why it works can often lead to trouble later on when someone else with less expertise tries to modify the code,
In this case, as the function is being passed to qsort its purpose is
fairly obvious, and anyone who could not at least work out what it is
doing and how it works is not ready to be working on their own as a
maintenance programmer.
or port it to a different language (where, for example, boolean true is not 1).
When translating between two languages it is better in my experience to
look at the purpose of regions of code and write appropriate
replacements than to simply translate on a function by function basis.
In the above case, the coding is rather silly. return (*x - *y); works just as well, with or without the parentheses, if the function is used only as a qsort() comparer.
No it doesn't. Or do you think that 0.1 - 0 is guaranteed to produce a
positive number rather than 0?
Your suggestion is not even guaranteed for int, since INT_MIN - 1 will
overflow, and the behaviour on overflow is undefined.
If the answer MUST be -1, 0, or +1 for some reason (like it is used by in some other comparison that requires that), it should be documented as such.
Agreed, but IMHO the code was probably written that way for correctness
rather than to produce exactly +0, -1 or 0.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro: http://clc-wiki.net/wiki/Intro_to_clc
Keith Thompson <ks***@mib.or g> writes: "Fred Kleinschmidt" <fr************ ******@boeing.c om> writes: "Spoon" <none> wrote in message news:44******** *************** @news.free.fr.. . Hello,
I've come across the following comparison function used as the 4th parameter in qsort()
int cmp(const void *px, const void *py) { const double *x = px, *y = py; return (*x > *y) - (*x < *y); }
It came "as-is" i.e. no comments.
Is it good style to write comparison functions that way?
Should the return values be made more explicit? Or would it be enough to add comments explaining why the function (usually) works? [snip] In the above case, the coding is rather silly. return (*x - *y); works just as well, with or without the parentheses, if the function is used only as a qsort() comparer.
No, it wouldn't. Consider what happens if the subtraction overflows. Or, since the operands are of type double, consider *x==0.5, *y==0.25; the result of the subtraction is 0.25, which yields 0 when (implicitly) converted to int.
The code above, "return (*x > *y) - (*x < *y);", is also probably
better-behaved in the presence of infinities and NaNs, at least quiet
NaNs.
--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Fred Kleinschmidt wrote: "Spoon" <none> wrote in message I've come across the following comparison function used as the 4th parameter in qsort()
int cmp(const void *px, const void *py) { const double *x = px, *y = py; return (*x > *y) - (*x < *y); }
It came "as-is" i.e. no comments.
Is it good style to write comparison functions that way?
Should the return values be made more explicit? Or would it be enough to add comments explaining why the function (usually) works?
.... snip ... In the above case, the coding is rather silly. return (*x - *y); works just as well, with or without the parentheses, if the function is used only as a qsort() comparer.
No it doesn't. That is subject to overflow and undefined
behaviour. The recommended code may have been due to me, and
caters to avoidance of flushing of instruction streams. It
specifies the types being compared in exactly one place, and works
all the time.
IMO there are very few non-beginners who would not understand the
code. There are many coders who fail to understand the reasons for
the code.
--
"If you want to post a followup via groups.google.c om, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell. org/google/>
Also see <http://www.safalra.com/special/googlegroupsrep ly/>
On Thu, 13 Apr 2006 00:37:39 +0100,
Flash Gordon <sp**@flash-gordon.me.uk> wrote
in Msg. <qi************ @news.flash-gordon.me.uk> In this case, as the function is being passed to qsort its purpose is fairly obvious, and anyone who could not at least work out what it is doing and how it works is not ready to be working on their own as a maintenance programmer.
A side note: I always like to name my qsort cmp functions starting with
'by_' because it makes for better English:
qsort(customer, ..., by_name);
robert
Robert Latest <bo*******@yaho o.com> wrote: Flash Gordon <sp**@flash-gordon.me.uk> wrote
In this case, as the function is being passed to qsort its purpose is fairly obvious, and anyone who could not at least work out what it is doing and how it works is not ready to be working on their own as a maintenance programmer.
A side note: I always like to name my qsort cmp functions starting with 'by_' because it makes for better English:
qsort(customer, ..., by_name);
Hey, that's not a bad idea at all! I might adopt that.
Richard
Richard Bos said: Robert Latest <bo*******@yaho o.com> wrote:
A side note: I always like to name my qsort cmp functions starting with 'by_' because it makes for better English:
qsort(customer, ..., by_name); Hey, that's not a bad idea at all!
Very good idea, in fact. Nice one, Robert.
I might adopt that.
Too late. I already have the papers right here, signed by a judge.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously) This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Debashish Chakravarty |
last post by:
Would it have been a good idea if the comparison function in quicksort
took three const void * parameters in, the third one for extra
information that might be required to compare the two objects, I think
the only way one can pass the information is by using global or static
variables.
|
by: Debashish Chakravarty |
last post by:
I am sorry, I meant qsort function not quicksort (I know qsort might
not implement quicksort) and since I am constrained to use google I
cannot reply to my previous post and hence his new post, apologies for
the inconvienience.
|
by: Dennis Chang |
last post by:
Hi all,
I was reading about function pointers and came across something which
intrigued me.
K&R2 calls qsort (pg.119) within main as so:
qsort( (void **) lineptr, 0, nlines-1, (int (*) (void *, void*))(numeric ?
numcmp : strcmp) );
I guess what interests me is the nameless function pointer and then the
|
by: Danilo Kempf |
last post by:
Folks,
maybe one of you could be of help with this question: I've got a relatively
portable application which I'm extending with a plugin interface. While
portability (from a C perspective) is going to hell just by using
dlopen()/LoadLibrary() respectively, I'm still trying to get it as clean as
possible.
I have a number of different quantums of data and a number of plugins. Since
any plugin can (and possibly will) touch any quantum...
|
by: aurgathor |
last post by:
Howdy,
How do I pass some function a generic comparison
function? I figured out one non-generic case, but
since this code got parameter declarations in two places,
it's obviously not generic.
TIA
#include <stdio.h>
| |
by: christer-sandberg |
last post by:
When I typecast a function and call it trough the casted pointer (se
code below) I get the warnings:
warning: function called through a non-compatible type
if this code is reached, the program will abort
and the gcc generates abort code for the call. This happens when I use
gcc 3.4 but not when I use 3.3. Is there any flag that can change this
behavior?
I am aware that ANSI-99 says (in 6.3.2.3-8): "If a converted pointer is
used to call...
|
by: Charles Sullivan |
last post by:
The library function 'qsort' is declared thus:
void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
If in my code I write:
int cmp_fcn(...);
int (*fcmp)() = &cmp_fcn;
qsort(..., fcmp);
then everything works. But if instead I code qsort as:
|
by: cmk128 |
last post by:
Hi
Why put * in front of the function name in the declaration?
int (*write)(struct inode *, struct file *, const char *, int);
thanks
from Peter (cmk128@hotmail.com)
|
by: tnowles00 |
last post by:
Hi friend,
what is the use of function pointer in c language and where it is
useful?
tell with simple example...?
plz help me.
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
| |
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |