Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #10570 > unrolled thread
| Started by | Stanley Rice <heconghui@gmail.com> |
|---|---|
| First post | 2011-09-20 06:51 -0700 |
| Last post | 2011-09-23 16:36 -0700 |
| Articles | 20 on this page of 36 — 17 participants |
Back to article view | Back to comp.lang.c
evaluate a generic swap function Stanley Rice <heconghui@gmail.com> - 2011-09-20 06:51 -0700
Re: evaluate a generic swap function jacob navia <jacob@spamsink.net> - 2011-09-20 16:01 +0200
Re: evaluate a generic swap function jt@toerring.de (Jens Thoms Toerring) - 2011-09-20 14:29 +0000
Re: evaluate a generic swap function jacob navia <jacob@spamsink.net> - 2011-09-20 21:13 +0200
Re: evaluate a generic swap function jt@toerring.de (Jens Thoms Toerring) - 2011-09-20 20:30 +0000
Re: evaluate a generic swap function Keith Thompson <kst-u@mib.org> - 2011-09-20 17:05 -0700
Re: evaluate a generic swap function gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-21 15:45 +0000
Re: evaluate a generic swap function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-21 09:33 -0700
Re: evaluate a generic swap function jacob navia <jacob@spamsink.net> - 2011-09-21 19:17 +0200
Re: evaluate a generic swap function gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-21 17:34 +0000
Re: evaluate a generic swap function Jack Foot <foot@dev.null.invalid> - 2011-09-21 18:12 +0000
Re: evaluate a generic swap function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-20 07:33 -0700
Re: evaluate a generic swap function ImpalerCore <jadill33@gmail.com> - 2011-09-20 08:26 -0700
Re: evaluate a generic swap function pete <pfiland@mindspring.com> - 2011-09-20 23:10 -0400
Re: evaluate a generic swap function "BartC" <bc@freeuk.com> - 2011-09-20 22:20 +0100
Re: evaluate a generic swap function jacob navia <jacob@spamsink.net> - 2011-09-20 23:23 +0200
Re: evaluate a generic swap function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-20 23:07 +0100
Re: evaluate a generic swap function Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-09-20 21:15 -0400
Re: evaluate a generic swap function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-21 03:17 -0700
Re: evaluate a generic swap function Gene <gene.ressler@gmail.com> - 2011-09-21 02:40 -0700
Re: evaluate a generic swap function Seebs <usenet-nospam@seebs.net> - 2011-09-23 01:46 +0000
Re: evaluate a generic swap function Nelu <tandauioan@gmail.com> - 2011-09-23 10:26 -0700
Re: evaluate a generic swap function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 18:36 +0100
Re: evaluate a generic swap function Nelu <tandauioan@gmail.com> - 2011-09-23 10:49 -0700
Re: evaluate a generic swap function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 20:18 +0100
Re: evaluate a generic swap function Nelu <tandauioan@gmail.com> - 2011-09-23 12:54 -0700
Re: evaluate a generic swap function James Kuyper <jameskuyper@verizon.net> - 2011-09-23 16:43 -0400
Re: evaluate a generic swap function Nelu <tandauioan@gmail.com> - 2011-09-23 13:49 -0700
Re: evaluate a generic swap function James Kuyper <jameskuyper@verizon.net> - 2011-09-23 17:44 -0400
Re: evaluate a generic swap function Nelu <tandauioan@gmail.com> - 2011-09-23 18:04 -0700
Re: evaluate a generic swap function Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 13:52 -0800
Re: evaluate a generic swap function Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 21:46 +0100
Re: evaluate a generic swap function Nelu <tandauioan@gmail.com> - 2011-09-23 13:59 -0700
Re: evaluate a generic swap function Seebs <usenet-nospam@seebs.net> - 2011-09-26 22:59 +0000
Re: evaluate a generic swap function pete <pfiland@mindspring.com> - 2011-09-23 18:19 -0400
Re: evaluate a generic swap function Nelu <tandauioan@gmail.com> - 2011-09-23 16:36 -0700
Page 1 of 2 [1] 2 Next page →
| From | Stanley Rice <heconghui@gmail.com> |
|---|---|
| Date | 2011-09-20 06:51 -0700 |
| Subject | evaluate a generic swap function |
| Message-ID | <fae63bac-e9c4-48e2-9c4f-e0269b2b3f2c@w8g2000yqi.googlegroups.com> |
Hello all
I wrote a "generic" swap function, which can swap some type, such as
int, double, long. But I don't know how to evaluate this function, and
don't know whether it's a good idea to use such a function. I hope you
can give me some suggestions.
void swap(void *left, void *right, size_t siz)
{
char *buf;
buf = (char *)malloc(sizeof(*buf) * siz);
memcpy(buf, left, siz);
memcpy(left, right, siz);
memcpy(right, buf, siz);
free(buf);
}
call this function in the following ways:
int a = 5;
int b = 4;
swap(&a, &b, sizeof(a));
Thanks.
[toc] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-09-20 16:01 +0200 |
| Message-ID | <j5a6bc$ubf$1@speranza.aioe.org> |
| In reply to | #10570 |
Le 20/09/11 15:51, Stanley Rice a écrit :
in standard C:
void swap(void *left, void *right, size_t siz)
{
char buf[siz];
memcpy(buf, left, siz);
memcpy(left, right, siz);
memcpy(right, buf, siz);
}
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2011-09-20 14:29 +0000 |
| Message-ID | <9drmajFiphU1@mid.uni-berlin.de> |
| In reply to | #10571 |
jacob navia <jacob@spamsink.net> wrote:
> Le 20/09/11 15:51, Stanley Rice a écrit :
> in standard C:
> void swap(void *left, void *right, size_t siz)
> {
> char buf[siz];
> memcpy(buf, left, siz);
> memcpy(left, right, siz);
> memcpy(right, buf, siz);
> }
One word of caution: this is standard C according to the 1999
standard, variable length arrays weren't part of the 1989 C
standard. If you want to cater also for C89 compiler, i.e.
use your original code, I would drop the cast from this line
> buf = (char *)malloc(sizeof(*buf) * siz);
buf = malloc( sizeof *buf * siz );
will do nicely unless you forgot to include <stdlib.h>.
(Note also that you don't need the parentheses around
'*buf' after 'sizeof', they are only needed if you take
the size of a type.)
You also might consider testing if malloc() suceeded by
checking that 'buf' has't been set to NULL. Of course,
the question then is on how to proceed. The way it's
written now the program would crash the program. You
could instead give the function a return value and re-
turn something indicating an error. Or you could use a
slower method for the swapping where you copy only smal-
ler parts of the data with a fixed size buffer in a loop.
Depends on how "bullet-proof" you need this function to
be.
Regards Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-09-20 21:13 +0200 |
| Message-ID | <j5aokc$eqb$1@speranza.aioe.org> |
| In reply to | #10573 |
Le 20/09/11 16:29, Jens Thoms Toerring a écrit :
> jacob navia<jacob@spamsink.net> wrote:
>> Le 20/09/11 15:51, Stanley Rice a écrit :
>> in standard C:
>
>> void swap(void *left, void *right, size_t siz)
>> {
>> char buf[siz];
>
>> memcpy(buf, left, siz);
>> memcpy(left, right, siz);
>> memcpy(right, buf, siz);
>> }
>
> One word of caution: this is standard C according to the 1999
> standard, variable length arrays weren't part of the 1989 C
> standard.
That one is not standard anymore, it has been obsoleted by the
committee. And if Microsoft doesn't follow it it doesn't matter
really, it is their problem.
Microsoft is the only major vendor that refuses C99.
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2011-09-20 20:30 +0000 |
| Message-ID | <9dsbevFfg2U1@mid.uni-berlin.de> |
| In reply to | #10590 |
jacob navia <jacob@spamsink.net> wrote:
> Le 20/09/11 16:29, Jens Thoms Toerring a écrit :
> > jacob navia<jacob@spamsink.net> wrote:
> >> Le 20/09/11 15:51, Stanley Rice a écrit :
> >> in standard C:
> >
> >> void swap(void *left, void *right, size_t siz)
> >> {
> >> char buf[siz];
> >
> >> memcpy(buf, left, siz);
> >> memcpy(left, right, siz);
> >> memcpy(right, buf, siz);
> >> }
> >
> > One word of caution: this is standard C according to the 1999
> > standard, variable length arrays weren't part of the 1989 C
> > standard.
> That one is not standard anymore, it has been obsoleted by the
> committee. And if Microsoft doesn't follow it it doesn't matter
> really, it is their problem.
Ok, let me rephrase that to "VLAs weren't part of the pre-
vious C standard from 1989";-) And I think it might matter
to the OP if he should be using a Microsoft compiler. And
then there also seem to be a few other compilers out there
in the wild without support for VLA's - at least I got a
bug report from someone just a few days ago about the "aCC:
HP C/aC++" compiler (from 2009) under HP-UX also not accep-
ting VLAs...
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-09-20 17:05 -0700 |
| Message-ID | <lnaa9y69pb.fsf@nuthaus.mib.org> |
| In reply to | #10598 |
jt@toerring.de (Jens Thoms Toerring) writes:
[...]
> Ok, let me rephrase that to "VLAs weren't part of the pre-
> vious C standard from 1989";-) And I think it might matter
> to the OP if he should be using a Microsoft compiler. And
> then there also seem to be a few other compilers out there
> in the wild without support for VLA's - at least I got a
> bug report from someone just a few days ago about the "aCC:
> HP C/aC++" compiler (from 2009) under HP-UX also not accep-
> ting VLAs...
VLAs are part of the *current* standard, C99.
In the latest draft of the *next* standard (which as yet has
no official status), VLAs are still part of the language, but
support for them is optional; an implementation may define the
macro __STDC_NO_VLA__ to indicate that it doesn't support them.
And of course the previous standard, C90, is still of considerable
significance; ISO says it's obsolete, but not everyone listens
to ISO.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2011-09-21 15:45 +0000 |
| Message-ID | <j5d0ps$bg7$1@news.xmission.com> |
| In reply to | #10615 |
In article <lnaa9y69pb.fsf@nuthaus.mib.org>, Keith Thompson <kst-u@mib.org> wrote: ... >And of course the previous standard, C90, is still of considerable >significance; ISO says it's obsolete, but not everyone listens >to ISO. Hold the phone there, Kiki my boy! If we admit that it is possible to not listen to ISO, then doesn't the whole raison d'etre of this newsgroup fade away? -- "The anti-regulation business ethos is based on the charmingly naive notion that people will not do unspeakable things for money." - Dana Carpender Quoted by Paul Ciszek (pciszek at panix dot com). But what I want to know is why is this diet/low-carb food author doing making pithy political/economic statements? Nevertheless, the above quote is dead-on, because, the thing is - business in one breath tells us they don't need to be regulated (which is to say: that they can morally self-regulate), then in the next breath tells us that corporations are amoral entities which have no obligations to anyone except their officers and shareholders, then in the next breath they tell us they don't need to be regulated (that they can morally self-regulate) ...
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2011-09-21 09:33 -0700 |
| Message-ID | <f76bc842-10a1-44a5-a7c6-fa7e04331dbe@fi7g2000vbb.googlegroups.com> |
| In reply to | #10644 |
On Sep 21, 6:45 pm, gaze...@shell.xmission.com (Kenny McCormack) wrote: > > If we admit that it is possible to not listen to ISO, then doesn't the whole > raison d'etre of this newsgroup fade away? > Not really. C90 C code will run pretty much anywhere. Code that is not conforming might work in most places, or it might only be useful for that particular platform. I got bitten by slash slash comments, I thought that by now it was surely safe to assume they would be accepted by any compiler. As it turned out, my very next compiler wouldn't accept them. I divide my code into four units; this program only, this platform only, this platform only, many programs, this program only, any platform, and many programs, many platforms. That helps with porting, it helps with resusing code, and it helps with keeping the design clean. Code in the second two sections should conform to ISO, code in the first two doesn't have to. However if you want a GUI, then you have to accept at least some code in the first two sections. -- Visit my website, play the Alice in Wonderland card game. http://www.malcolmmclean.site11.com/www
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-09-21 19:17 +0200 |
| Message-ID | <j5d66r$dpl$1@speranza.aioe.org> |
| In reply to | #10644 |
Le 21/09/11 17:45, Kenny McCormack a écrit : > In article<lnaa9y69pb.fsf@nuthaus.mib.org>, > Keith Thompson<kst-u@mib.org> wrote: > ... >> And of course the previous standard, C90, is still of considerable >> significance; ISO says it's obsolete, but not everyone listens >> to ISO. > > Hold the phone there, Kiki my boy! > > If we admit that it is possible to not listen to ISO, then doesn't the whole > raison d'etre of this newsgroup fade away? > Of course this is the same guy that always has the word "the C standard exists for a reason"... to be held against anybody that disagrees with him...
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2011-09-21 17:34 +0000 |
| Message-ID | <j5d775$mcb$1@news.xmission.com> |
| In reply to | #10656 |
In article <j5d66r$dpl$1@speranza.aioe.org>, jacob navia <jacob@jspamsink.org> wrote: >Le 21/09/11 17:45, Kenny McCormack a écrit : >> In article<lnaa9y69pb.fsf@nuthaus.mib.org>, >> Keith Thompson<kst-u@mib.org> wrote: >> ... >>> And of course the previous standard, C90, is still of considerable >>> significance; ISO says it's obsolete, but not everyone listens >>> to ISO. >> >> Hold the phone there, Kiki my boy! >> >> If we admit that it is possible to not listen to ISO, then doesn't the whole >> raison d'etre of this newsgroup fade away? >> > >Of course this is the same guy that always has the word >"the C standard exists for a reason"... to be held against >anybody that disagrees with him... Yup. Now, obviously, there are ways to weasel out of this and explain how what he wrote isn't really a repudiation of everything he stands for, but the fact remains that I think I was hardly alone in being shocked and amazed to hear those words from his mouth (*). (*) Metaphorically speaking, of course... -- (This discussion group is about C, ...) Wrong. It is only OCCASIONALLY a discussion group about C; mostly, like most "discussion" groups, it is off-topic Rorsharch [sic] revelations of the childhood traumas of the participants...
[toc] | [prev] | [next] | [standalone]
| From | Jack Foot <foot@dev.null.invalid> |
|---|---|
| Date | 2011-09-21 18:12 +0000 |
| Message-ID | <j5d9e0$mpj$1@speranza.aioe.org> |
| In reply to | #10658 |
On Wed, 21 Sep 2011 17:34:29 +0000, Kenny McCormack wrote: > In article <j5d66r$dpl$1@speranza.aioe.org>, jacob navia > <jacob@jspamsink.org> wrote: >>Le 21/09/11 17:45, Kenny McCormack a écrit : >>> In article<lnaa9y69pb.fsf@nuthaus.mib.org>, Keith >>> Thompson<kst-u@mib.org> wrote: ... >>>> And of course the previous standard, C90, is still of considerable >>>> significance; ISO says it's obsolete, but not everyone listens to >>>> ISO. >>> >>> Hold the phone there, Kiki my boy! >>> >>> If we admit that it is possible to not listen to ISO, then doesn't the >>> whole raison d'etre of this newsgroup fade away? >>> >>> >>Of course this is the same guy that always has the word "the C standard >>exists for a reason"... to be held against anybody that disagrees with >>him... > > Yup. Now, obviously, there are ways to weasel out of this and explain > how what he wrote isn't really a repudiation of everything he stands > for, but the fact remains that I think I was hardly alone in being > shocked and amazed to hear those words from his mouth (*). I sure reckon the difference this time is that Jacob was taking the part of ISO. For some reason Keith seems to have a strange obsession with Jacob, and he's obviously willing to abandon his principles if that lets him get in a cheap attack on Jacob. Sad...
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2011-09-20 07:33 -0700 |
| Message-ID | <f2f60fe3-fb49-4577-821b-f672d86f3bac@1g2000vbu.googlegroups.com> |
| In reply to | #10570 |
On Sep 20, 4:51 pm, Stanley Rice <hecong...@gmail.com> wrote: > Hello all > > I wrote a "generic" swap function, which can swap some type, such as > int, double, long. But I don't know how to evaluate this function, and > don't know whether it's a good idea to use such a function. I hope you > can give me some suggestions. > The function calls malloc to allocate a temporary buffer. This means that it's vulnerable to failure. It's also likely to be inefficient. You can write swap() as a byte swapping loop, which avoids the need for a malloc(). The problem is that most calls will be to arrays of ints or other larger types. You can probably get a 4x speed up if you know that data is a multiple of four and aligned. What this means is that swap() is really a function, like memcpy, best implemented by the compiler, which can apply patches to speed up common cases. E.g. swapping two basic types, which is an obvious use for the function, can be turned into a sequence of three instructions, or even sometimes eliminated altogether. -- Visit my website - JPEG decoder available in Basic Algorithms http://www.malcolmmclean.site11.com/www
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2011-09-20 08:26 -0700 |
| Message-ID | <640a6fdc-0001-4de0-ba3d-d7ab5abcdc69@z18g2000yqb.googlegroups.com> |
| In reply to | #10574 |
On Sep 20, 10:33 am, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Sep 20, 4:51 pm, Stanley Rice <hecong...@gmail.com> wrote:> Hello all
>
> > I wrote a "generic" swap function, which can swap some type, such as
> > int, double, long. But I don't know how to evaluate this function, and
> > don't know whether it's a good idea to use such a function. I hope you
> > can give me some suggestions.
>
> The function calls malloc to allocate a temporary buffer. This means
> that it's vulnerable to failure. It's also likely to be inefficient.
>
> You can write swap() as a byte swapping loop, which avoids the need
> for a malloc(). The problem is that most calls will be to arrays of
> ints or other larger types. You can probably get a 4x speed up if you
> know that data is a multiple of four and aligned.
> What this means is that swap() is really a function, like memcpy, best
> implemented by the compiler, which can apply patches to speed up
> common cases. E.g. swapping two basic types, which is an obvious use
> for the function, can be turned into a sequence of three
> instructions, or even sometimes eliminated altogether.
One method to consider is to write macros to declare the function
prototype and definition of a swap specialized to the type.
\code snippet
#define C_SWAP_PROTO( NAME, TYPE ) void c_swap_##NAME( TYPE* left,
TYPE* right )
#define C_SWAP_IMPL( NAME, TYPE ) \
void c_swap_##NAME( TYPE* left, TYPE* right ) \
{ \
TYPE tmp; \
\
tmp = *left; \
*left = *right; \
*right = tmp; \
}
\endcode
Then, if one wants to swap a particular type, they declare the
prototype and definition where needed and use the generated function
name to swap the objects. The advantage is that in a library setting,
one can create a generic template for a swap without the need to
maintain an arbitrary list of swap functions, like c_swap_int,
c_swap_long, c_swap_my_struct, etc.
The reason for the 'NAME' attribute is that types with spaces in them
obviously cause problems in the function prototypes. You could use
them like the following.
\code snippet
#include <stdio.h>
#include <stdlib.h>
C_SWAP_PROTO( uint, unsigned int );
int main( void )
{
unsigned int u1 = 10;
unsigned int u2 = 20;
c_swap_uint( &u1, &u2 );
printf( "[u1,u2] = [%u,%u]\n", u1, u2 );
return EXIT_SUCCESS;
}
/* Important to *not* add the semicolon after the IMPL macro */
C_SWAP_IMPL( uint, unsigned int )
\endcode
I fully acknowledge that some may consider this "function template" a
coding horror. But at the same time, I have found this kind of setup
very convenient from a maintenance perspective.
Best regards,
John D.
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-09-20 23:10 -0400 |
| Message-ID | <4E7955A1.440D@mindspring.com> |
| In reply to | #10576 |
ImpalerCore wrote:
>
> On Sep 20, 10:33 am, Malcolm McLean <malcolm.mcle...@btinternet.com>
> wrote:
> > On Sep 20, 4:51 pm, Stanley Rice <hecong...@gmail.com> wrote:> Hello all
> >
> > > I wrote a "generic" swap function, which can swap some type, such as
> > > int, double, long. But I don't know how to evaluate this function, and
> > > don't know whether it's a good idea to use such a function. I hope you
> > > can give me some suggestions.
> >
> > The function calls malloc to allocate a temporary buffer. This means
> > that it's vulnerable to failure. It's also likely to be inefficient.
> >
> > You can write swap() as a byte swapping loop, which avoids the need
> > for a malloc(). The problem is that most calls will be to arrays of
> > ints or other larger types. You can probably get a 4x speed up if you
> > know that data is a multiple of four and aligned.
> > What this means is that swap() is really a function, like memcpy, best
> > implemented by the compiler, which can apply patches to speed up
> > common cases. E.g. swapping two basic types, which is an obvious use
> > for the function, can be turned into a sequence of three
> > instructions, or even sometimes eliminated altogether.
>
> One method to consider is to write macros to declare the function
> prototype and definition of a swap specialized to the type.
>
> \code snippet
> #define C_SWAP_PROTO( NAME, TYPE ) void c_swap_##NAME( TYPE* left,
> TYPE* right )
>
> #define C_SWAP_IMPL( NAME, TYPE ) \
> void c_swap_##NAME( TYPE* left, TYPE* right ) \
> { \
> TYPE tmp; \
> \
> tmp = *left; \
> *left = *right; \
> *right = tmp; \
> }
> \endcode
>
> Then, if one wants to swap a particular type, they declare the
> prototype and definition where needed and use the generated function
> name to swap the objects. The advantage is that in a library setting,
> one can create a generic template for a swap without the need to
> maintain an arbitrary list of swap functions, like c_swap_int,
> c_swap_long, c_swap_my_struct, etc.
>
> The reason for the 'NAME' attribute is that types with spaces in them
> obviously cause problems in the function prototypes. You could use
> them like the following.
>
> \code snippet
> #include <stdio.h>
> #include <stdlib.h>
>
> C_SWAP_PROTO( uint, unsigned int );
>
> int main( void )
> {
> unsigned int u1 = 10;
> unsigned int u2 = 20;
>
> c_swap_uint( &u1, &u2 );
>
> printf( "[u1,u2] = [%u,%u]\n", u1, u2 );
>
> return EXIT_SUCCESS;
> }
>
> /* Important to *not* add the semicolon after the IMPL macro */
> C_SWAP_IMPL( uint, unsigned int )
> \endcode
>
> I fully acknowledge that some may consider this "function template" a
> coding horror. But at the same time, I have found this kind of setup
> very convenient from a maintenance perspective.
I use these macros:
#define SWAP(N, A, B, T) \
(MOV##N((T), (A)), MOV##N((A), (B)), MOV##N((B), (T)))
#define MOVi(A, B) ((void)(*(A) = *(B)))
#define MOVa(A, B) ((void)memcpy((A), (B), sizeof *(A)))
MOVa is for when *(A) is of array type.
MOVi is for when *(A) isn't of array type.
--
pete
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-09-20 22:20 +0100 |
| Message-ID | <j5b03r$ar$1@dont-email.me> |
| In reply to | #10570 |
"Stanley Rice" <heconghui@gmail.com> wrote in message
news:fae63bac-e9c4-48e2-9c4f-e0269b2b3f2c@w8g2000yqi.googlegroups.com...
> I wrote a "generic" swap function, which can swap some type, such as
> int, double, long. But I don't know how to evaluate this function, and
> don't know whether it's a good idea to use such a function. I hope you
> can give me some suggestions.
>
> void swap(void *left, void *right, size_t siz)
> {
> char *buf;
>
> buf = (char *)malloc(sizeof(*buf) * siz);
>
> memcpy(buf, left, siz);
> memcpy(left, right, siz);
> memcpy(right, buf, siz);
>
> free(buf);
> }
>
> call this function in the following ways:
> int a = 5;
> int b = 4;
> swap(&a, &b, sizeof(a));
What are the most common things to swap? If they are basic types such as
ints or chars, then your function will be inefficient, if you're planning to
do a lot of swapping. You also have to consider than malloc() calls are
costly, and subject to failure.
Since you will usually know what types of being swapped, it wouldn't be
difficult to add a few streamlined versions of swap(): swap_int(),
swap_double(), etc.
Or the size can be tested inside swap(), and values such as 4 or 8 can be
identified and deal with quickly without any allocations.
Also, if the size of the type is often going to be small, you might want to
just use a fixed-size buffer, such as:
char buf_fixed[256];
and use that, without any memory management, if the size happens to be <=
256, otherwise you'd need malloc(). (VLAs which someone suggested using are
also viable, if the size is not going to be so huge that you get stack
overflows.)
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-09-20 23:23 +0200 |
| Message-ID | <j5b084$2t8$2@speranza.aioe.org> |
| In reply to | #10607 |
Le 20/09/11 23:20, BartC a écrit : > > What are the most common things to swap? If they are basic types such as > ints or chars, then your function will be inefficient, if you're > planning to > do a lot of swapping. You also have to consider than malloc() calls are > costly, and subject to failure. > Happily the malloc calls are not needed in standard C.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-09-20 23:07 +0100 |
| Message-ID | <0.48a85f6c18734fbc72cf.20110920230700BST.87mxdyswaj.fsf@bsb.me.uk> |
| In reply to | #10608 |
jacob navia <jacob@spamsink.net> writes:
> Le 20/09/11 23:20, BartC a écrit :
>>
>> What are the most common things to swap? If they are basic types such as
>> ints or chars, then your function will be inefficient, if you're
>> planning to
>> do a lot of swapping. You also have to consider than malloc() calls are
>> costly, and subject to failure.
>
> Happily the malloc calls are not needed in standard C.
You don't need them in C90 either:
#define CHUNK_SIZE 512
void swap(void *vp1, void *vp2, size_t size)
{
char *cp1 = vp1, *cp2 = vp2;
do {
char tmp[CHUNK_SIZE];
size_t csz = size > CHUNK_SIZE ? CHUNK_SIZE : size;
memcpy(tmp, cp1, csz);
memcpy(cp1, cp2, csz);
memcpy(cp2, tmp, csz);
dst += csz;
src += csz;
} while (size -= csz);
}
(untested).
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-09-20 21:15 -0400 |
| Message-ID | <j5bdtu$i41$1@dont-email.me> |
| In reply to | #10570 |
On 9/20/2011 9:51 AM, Stanley Rice wrote:
> Hello all
>
> I wrote a "generic" swap function, which can swap some type, such as
> int, double, long. But I don't know how to evaluate this function, and
> don't know whether it's a good idea to use such a function. I hope you
> can give me some suggestions.
>
> void swap(void *left, void *right, size_t siz)
> {
> char *buf;
>
> buf = (char *)malloc(sizeof(*buf) * siz);
The cast is harmless but unnecessary. And since you're already
assuming that `siz' is a byte count, the multiplication by unity is
also unnecessary, although harmless. Just saying.
> memcpy(buf, left, siz);
If malloc() fails to deliver the requested amount of memory and
returns NULL, you'll be in trouble. You'd be in even worse trouble
using a C99 variable-length array instead of calling malloc(), because
malloc() can at least tell you when it fails, while a VLA cannot. Also,
malloc(0) is well-defined, while a VLA of zero elements is a constraint
violation. ("Swapping" two zero-length objects is something of a corner
case, it's true, but functions should behave nicely in the corners if
possible: consider the memxxx() functions with zero size.)
> memcpy(left, right, siz);
> memcpy(right, buf, siz);
> free(buf);
> }
>
> call this function in the following ways:
> int a = 5;
> int b = 4;
> swap(&a,&b, sizeof(a));
Although your function will work (if malloc() succeeds), I don't
think it's very attractive. An operation is worth encapsulating in
a utility function if it's difficult or tricky in some way, or if the
function can somehow perform the operation more cheaply or conveniently
than free-hand code. I doubt that this particular function scores on
either point: It encapsulates a simple operation, and probably uses
more time and memory than a simple implementation would.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2011-09-21 03:17 -0700 |
| Message-ID | <0a2127b6-777b-4129-be79-e75e37dbb0d3@en1g2000vbb.googlegroups.com> |
| In reply to | #10621 |
On Sep 21, 4:15 am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote: > An operation is worth encapsulating in > a utility function if it's difficult or tricky in some way, or if the > function can somehow perform the operation more cheaply or conveniently > than free-hand code. id > temp = a; a = b; b = temp; or swap(&a, &b, sizeof(int)); I think there's a case for the second. In reality it would be embedded in some tedious logic which requires variables to be swapped, and anything that makes such code more readable is a plus. -- Website: http://www.malcolmmclean.site11.com/www
[toc] | [prev] | [next] | [standalone]
| From | Gene <gene.ressler@gmail.com> |
|---|---|
| Date | 2011-09-21 02:40 -0700 |
| Message-ID | <263d2c9d-ec15-4085-b83c-0b599fcb82b6@f17g2000yqh.googlegroups.com> |
| In reply to | #10570 |
On Sep 20, 9:51 am, Stanley Rice <hecong...@gmail.com> wrote:
> Hello all
>
> I wrote a "generic" swap function, which can swap some type, such as
> int, double, long. But I don't know how to evaluate this function, and
> don't know whether it's a good idea to use such a function. I hope you
> can give me some suggestions.
>
> void swap(void *left, void *right, size_t siz)
> {
> char *buf;
>
> buf = (char *)malloc(sizeof(*buf) * siz);
>
> memcpy(buf, left, siz);
> memcpy(left, right, siz);
> memcpy(right, buf, siz);
>
> free(buf);
>
> }
>
> call this function in the following ways:
> int a = 5;
> int b = 4;
> swap(&a, &b, sizeof(a));
Others have mentioned but not shown how you could implement this
without the potentially large and failure-prone buffer:
void swap(void *left, void *right, size_t siz)
{
char *p = left, *q = right;
while (siz--) {
char t = *p;
*p = *q;
*q = t;
p++; q++;
}
}
With a decent compiler (gcc included), this will be nicely optimized
to move as many bytes as possible with aligned word operations.
And if you say something like:
int a = 2, b = 1;
swap(&a, &b, sizeof a);
The generated code resulting from automatic inlining will be nearly
identical to what you'd get for
int a = 2, b = 1;
int t = a; a = b; b = t;
So back to your original question, it's fine to use a generic swap if
you avoid the malloc().
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web