Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #90116 > unrolled thread

EXIT_SUCCESS

Started byReal Troll <real.troll@trolls.com>
First post2016-07-08 00:00 -0300
Last post2016-08-01 10:09 -0400
Articles 20 on this page of 74 — 29 participants

Back to article view | Back to comp.lang.c


Contents

  EXIT_SUCCESS Real Troll <real.troll@trolls.com> - 2016-07-08 00:00 -0300
    Re: EXIT_SUCCESS luser droog <luser.droog@gmail.com> - 2016-07-07 19:54 -0700
    Re: EXIT_SUCCESS Ian Collins <ian-news@hotmail.com> - 2016-07-08 15:03 +1200
    Re: EXIT_SUCCESS James Kuyper <jameskuyper@verizon.net> - 2016-07-07 23:20 -0400
      Re: EXIT_SUCCESS Richard Heathfield <rjh@cpax.org.uk> - 2016-07-08 10:19 +0100
        Re: EXIT_SUCCESS Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-07-08 03:25 -0700
          Re: EXIT_SUCCESS Richard Heathfield <rjh@cpax.org.uk> - 2016-07-08 13:49 +0100
          Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-08 08:33 -0700
            Re: EXIT_SUCCESS Gareth Owen <gwowen@gmail.com> - 2016-07-08 18:03 +0100
              Re: EXIT_SUCCESS Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-07-08 19:11 +0100
                Re: EXIT_SUCCESS "Osmium" <r124c4u102@comcast.net> - 2016-07-08 14:25 -0500
                  Re: EXIT_SUCCESS Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-07-08 20:34 +0100
                    Re: EXIT_SUCCESS Ken Brody <kenbrody@spamcop.net> - 2016-07-11 19:10 -0400
                  Re: EXIT_SUCCESS Robert Wessel <robertwessel2@yahoo.com> - 2016-07-10 01:21 -0500
                  Re: EXIT_SUCCESS Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-07-10 16:09 -0600
                  Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-10 16:01 -0700
                    Re: EXIT_SUCCESS "Osmium" <r124c4u102@comcast.net> - 2016-07-10 18:30 -0500
                      Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-10 17:00 -0700
                      Re: EXIT_SUCCESS James Kuyper <jameskuyper@verizon.net> - 2016-07-10 22:43 -0400
                        Re: EXIT_SUCCESS Siri Cruise <chine.bleu@yahoo.com> - 2016-07-10 22:31 -0700
                          Re: EXIT_SUCCESS raltbos@xs4all.nl (Richard Bos) - 2016-07-11 08:24 +0000
                          Re: EXIT_SUCCESS Ken Brody <kenbrody@spamcop.net> - 2016-07-11 19:18 -0400
                    Re: EXIT_SUCCESS gazelle@shell.xmission.com (Kenny McCormack) - 2016-07-11 00:47 +0000
                  Re: EXIT_SUCCESS gordonb.0aikd@burditt.org (Gordon Burditt) - 2016-07-12 18:52 -0500
                    Re: EXIT_SUCCESS "James R. Kuyper" <jameskuyper@verizon.net> - 2016-07-12 20:32 -0400
                      Re: EXIT_SUCCESS Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-07-12 20:59 -0600
                      Re: EXIT_SUCCESS gordonb.a2m2l@burditt.org (Gordon Burditt) - 2016-07-13 02:11 -0500
                        Re: EXIT_SUCCESS James Kuyper <jameskuyper@verizon.net> - 2016-07-13 11:26 -0400
                          Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-13 08:48 -0700
                      Re: EXIT_SUCCESS Tim Rentsch <txr@alumni.caltech.edu> - 2016-07-18 09:54 -0700
              Re: EXIT_SUCCESS James Kuyper <jameskuyper@verizon.net> - 2016-07-08 17:46 -0400
                Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-09 13:13 -0700
                  Re: EXIT_SUCCESS jgh@mdfs.net - 2016-07-25 04:42 -0700
                    Re: EXIT_SUCCESS Richard Heathfield <rjh@cpax.org.uk> - 2016-07-25 13:07 +0100
                      Re: EXIT_SUCCESS Udyant Wig <udyant.wig@gmail.com> - 2016-07-25 20:05 +0530
                      Re: EXIT_SUCCESS raltbos@xs4all.nl (Richard Bos) - 2016-07-25 16:06 +0000
                        Re: EXIT_SUCCESS Richard Heathfield <rjh@cpax.org.uk> - 2016-07-25 17:41 +0100
                          Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-25 11:04 -0700
                            Re: EXIT_SUCCESS Richard Heathfield <rjh@cpax.org.uk> - 2016-07-25 19:14 +0100
                              Re: EXIT_SUCCESS BartC <bc@freeuk.com> - 2016-07-25 22:00 +0100
                                Re: EXIT_SUCCESS Richard Heathfield <rjh@cpax.org.uk> - 2016-07-25 22:03 +0100
                                  Re: EXIT_SUCCESS BartC <bc@freeuk.com> - 2016-07-25 22:41 +0100
                                    Re: EXIT_SUCCESS jadill33@gmail.com - 2016-07-25 14:50 -0700
                                Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-25 15:04 -0700
                            Re: EXIT_SUCCESS David Brown <david.brown@hesbynett.no> - 2016-07-26 10:43 +0200
                          Re: EXIT_SUCCESS jadill33@gmail.com - 2016-07-25 14:41 -0700
                            Re: EXIT_SUCCESS David Brown <david.brown@hesbynett.no> - 2016-07-26 10:59 +0200
                              Re: EXIT_SUCCESS jadill33@gmail.com - 2016-07-27 06:20 -0700
                                Re: EXIT_SUCCESS Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-07-27 15:44 +0100
                                  Re: EXIT_SUCCESS Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-07-27 16:22 +0100
                                  Re: EXIT_SUCCESS Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-07-27 11:20 -0600
                                  Re: EXIT_SUCCESS luser droog <luser.droog@gmail.com> - 2016-07-27 15:32 -0700
                                    Re: EXIT_SUCCESS Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-07-28 14:47 +0100
                    Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-25 08:46 -0700
                      Re: EXIT_SUCCESS David Brown <david.brown@hesbynett.no> - 2016-07-26 12:44 +0200
                        Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-26 08:24 -0700
                          Re: EXIT_SUCCESS David Brown <david.brown@hesbynett.no> - 2016-07-26 19:26 +0200
                        Re: EXIT_SUCCESS BartC <bc@freeuk.com> - 2016-07-26 18:03 +0100
                Re: EXIT_SUCCESS Ken Brody <kenbrody@spamcop.net> - 2016-07-11 19:15 -0400
                  Re: EXIT_SUCCESS supercat@casperkitty.com - 2016-07-11 16:46 -0700
                  Re: EXIT_SUCCESS raltbos@xs4all.nl (Richard Bos) - 2016-07-15 13:51 +0000
                    Re: EXIT_SUCCESS supercat@casperkitty.com - 2016-07-15 08:07 -0700
                    Re: EXIT_SUCCESS Ken Brody <kenbrody@spamcop.net> - 2016-07-15 14:33 -0400
                      Re: EXIT_SUCCESS raltbos@xs4all.nl (Richard Bos) - 2016-07-23 09:07 +0000
                        Re: EXIT_SUCCESS Randy Howard <rhoward.mx@EverybodyUsesIt.com> - 2016-07-23 16:44 -0500
                          Re: EXIT_SUCCESS Ken Brody <kenbrody@spamcop.net> - 2016-07-25 10:36 -0400
                            Re: EXIT_SUCCESS Randy Howard <rhoward.mx@EverybodyUsesIt.com> - 2016-07-25 15:28 -0500
                Re: EXIT_SUCCESS Rosario19 <Ros@invalid.invalid> - 2016-07-18 09:45 +0200
          Re: EXIT_SUCCESS gordonb.bitq1@burditt.org (Gordon Burditt) - 2016-07-08 17:56 -0500
    Re: EXIT_SUCCESS Keith Thompson <kst-u@mib.org> - 2016-07-08 08:35 -0700
      Re: EXIT_SUCCESS luser droog <luser.droog@gmail.com> - 2016-07-31 15:03 -0700
        Re: EXIT_SUCCESS Real Troll <real.troll@trolls.com> - 2016-07-31 18:09 -0400
        Re: EXIT_SUCCESS luser droog <luser.droog@gmail.com> - 2016-07-31 15:36 -0700
        Re: EXIT_SUCCESS James Kuyper <jameskuyper@verizon.net> - 2016-08-01 10:09 -0400

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#91060

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-07-25 22:03 +0100
Message-ID<nn5ur2$vdd$1@dont-email.me>
In reply to#91059
On 25/07/16 22:00, BartC wrote:
> On 25/07/2016 19:14, Richard Heathfield wrote:
>> On 25/07/16 19:04, Keith Thompson wrote:
>>> Richard Heathfield <rjh@cpax.org.uk> writes:
>
>>>>>>      size_t maxval = sizeof numbers / sizeof numbers[0] - 1;
>>>>>>      return numbers[a <= maxval ? a : maxval];
>
>>>> A slightly better solution (which, of course, I thought of /after/
>>>> posting) would have been to make maxval static.
>>>
>>> And const?
>>
>> Yep. I thought of that one after posting the one I thought of after
>> posting the first one. Shades of IEFBR14.
>
> So:
>
>   static const size_t maxval = ...
>
> before you've even started expressing the size of the array?

Give it a rest, BartC.

> I might go with:
>
> #define LEN(a) (sizeof (a)/sizeof ((a)[0]))
> #define UPB(a) (LEN(a)-1)

And that makes things /simpler/? Furrfu!

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#91062

FromBartC <bc@freeuk.com>
Date2016-07-25 22:41 +0100
Message-ID<nn611p$8av$1@dont-email.me>
In reply to#91060
On 25/07/2016 22:03, Richard Heathfield wrote:
> On 25/07/16 22:00, BartC wrote:

>>
>> So:
>>
>>   static const size_t maxval = ...
>>
>> before you've even started expressing the size of the array?
>
> Give it a rest, BartC.

People have different opinions on how to write code.

And they're entitled to express their opinions here.

I think your example is heavy-handed for what is supposed to be a 
compile-time constant.

>> I might go with:
>>
>> #define LEN(a) (sizeof (a)/sizeof ((a)[0]))
>> #define UPB(a) (LEN(a)-1)
>
> And that makes things /simpler/? Furrfu!

You write those macros once.

You use them everywhere.

Or you could choose to write 'sizeof(A)/sizeof(A[0])' over and over again.

-- 
Bartc



[toc] | [prev] | [next] | [standalone]


#91064

Fromjadill33@gmail.com
Date2016-07-25 14:50 -0700
Message-ID<b75fc3d1-6bc7-414c-9e32-0ae27b646378@googlegroups.com>
In reply to#91062
On Monday, July 25, 2016 at 5:41:19 PM UTC-4, Bart wrote:
> On 25/07/2016 22:03, Richard Heathfield wrote:
> > On 25/07/16 22:00, BartC wrote:
> 
> >>
> >> So:
> >>
> >>   static const size_t maxval = ...
> >>
> >> before you've even started expressing the size of the array?
> >
> > Give it a rest, BartC.
> 
> People have different opinions on how to write code.
> 
> And they're entitled to express their opinions here.
> 
> I think your example is heavy-handed for what is supposed to be a 
> compile-time constant.
> 
> >> I might go with:
> >>
> >> #define LEN(a) (sizeof (a)/sizeof ((a)[0]))
> >> #define UPB(a) (LEN(a)-1)
> >
> > And that makes things /simpler/? Furrfu!
> 
> You write those macros once.
> 
> You use them everywhere.
> 
> Or you could choose to write 'sizeof(A)/sizeof(A[0])' over and over again.

I've always liked 'sizeof_array' as the name I use for this macro.  LEN is
too generic for my tastes.

And yes, it's worth using a macro if you have to do it more than once.
I can't imagine wanting to maintaining dozens of different instances of
this construct scattered throughout a codebase.  My test code is made up
of statically defined arrays of stuff, so I see it plenty enough.

Best regards,
John D.

[toc] | [prev] | [next] | [standalone]


#91066

FromKeith Thompson <kst-u@mib.org>
Date2016-07-25 15:04 -0700
Message-ID<ln7fc9cr2b.fsf@kst-u.example.com>
In reply to#91059
BartC <bc@freeuk.com> writes:
> On 25/07/2016 19:14, Richard Heathfield wrote:
>> On 25/07/16 19:04, Keith Thompson wrote:
>>> Richard Heathfield <rjh@cpax.org.uk> writes:
>
>>>>>>      size_t maxval = sizeof numbers / sizeof numbers[0] - 1;
>>>>>>      return numbers[a <= maxval ? a : maxval];
>
>>>> A slightly better solution (which, of course, I thought of /after/
>>>> posting) would have been to make maxval static.
>>>
>>> And const?
>>
>> Yep. I thought of that one after posting the one I thought of after
>> posting the first one. Shades of IEFBR14.
>
> So:
>
>   static const size_t maxval = ...
>
> before you've even started expressing the size of the array?

What?

The size of the array is determined by the initializer.

We were merely talking about adding "const" and "static" to the existing
declaration of "maxval", like this:

static const char *get_foo(size_t a)
{
  static const char *numbers[] =
  {
    "zero",
    "one",
    "two",
    "three",
    "four"
  };
  static const size_t maxval = sizeof numbers / sizeof numbers[0] - 1;

  return numbers[a <= maxval ? a : maxval];
}

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#91081

FromDavid Brown <david.brown@hesbynett.no>
Date2016-07-26 10:43 +0200
Message-ID<nn77rf$e7s$1@dont-email.me>
In reply to#91041
On 25/07/16 20:04, Keith Thompson wrote:
> Richard Heathfield <rjh@cpax.org.uk> writes:
>> On 25/07/16 17:06, Richard Bos wrote:
>>> Richard Heathfield <rjh@cpax.org.uk> wrote:
>>>
>>>> On 25/07/16 12:42, jgh@mdfs.net wrote:
>>>
>>>> static const char *get_foo(size_t a)
>>>> {
>>>>     static const char *numbers[] =
>>>>     {
>>>>       "zero",
>>>>       "one",
>>>>       "two",
>>>>       "three",
>>>>       "four"
>>>>     };
>>>>     size_t maxval = sizeof numbers / sizeof numbers[0] - 1;
>>>>
>>>>     return numbers[a <= maxval ? a : maxval];
>>>> }
>>>
>>> A good solution,
>>
>> A slightly better solution (which, of course, I thought of /after/ 
>> posting) would have been to make maxval static.
> 
> And const?
> 

That would seem natural.

Neither "static" nor "const" will change the efficiency of the generated
code (assuming basic optimisations), since the compiler can see that
maxval never changes and cannot be accessed outside the function.  My
normal practice here would be to make maxval const, but not static -
since it is obvious that the value is a compile-time constant, there is
no need to ask the compiler explicitly to preserve it across function
calls by adding "static".  But it is not something I would be
particularly concerned about.

[toc] | [prev] | [next] | [standalone]


#91063

Fromjadill33@gmail.com
Date2016-07-25 14:41 -0700
Message-ID<9c263285-548c-4f42-8d54-94ba1c3628ab@googlegroups.com>
In reply to#91032
On Monday, July 25, 2016 at 12:42:00 PM UTC-4, Richard Heathfield wrote:
> On 25/07/16 17:06, Richard Bos wrote:
> > Richard Heathfield <r...@...uk> wrote:
> >
> >> On 25/07/16 12:42, j...@...net wrote:
> >
> >> static const char *get_foo(size_t a)
> >> {
> >>     static const char *numbers[] =
> >>     {
> >>       "zero",
> >>       "one",
> >>       "two",
> >>       "three",
> >>       "four"
> >>     };
> >>     size_t maxval = sizeof numbers / sizeof numbers[0] - 1;
> >>
> >>     return numbers[a <= maxval ? a : maxval];
> >> }
> >
> > A good solution,
> 
> A slightly better solution (which, of course, I thought of /after/ 
> posting) would have been to make maxval static.
> 
> > but it only works well if the accepted values of a are
> > contiguous (or nearly so, with at most a handful of ugly extra defaults
> > scattered through the array).
> 
> That's right. I fitted the solution to the problem. If the problem 
> changes, sometimes the solution changes too (for example, to a perfect 
> hash or even some kind of dictionary).

I think I have you covered here.

\code
#include <stdio.h>
#include <assert.h>

typedef struct value_string
{
  unsigned int value;
  const char* strptr;
} value_string;

const char*
val_to_str( const unsigned int val, const value_string* vs, const char* unknown_str );

const char*
try_val_to_str( const unsigned int val, const value_string *vs );

const char*
try_val_to_str_idx( const unsigned int val, const value_string *vs, int *idx );

/* Tries to match 'val' against each element in the value_string array 'vs'.
   Returns the associated string ptr on a match, 'unknown_str' on failure. */
const char*
val_to_str( const unsigned int val, const value_string* vs, const char* unknown_str )
{
  const char* str;

  str = try_val_to_str( val, vs );
  
  return str != NULL ? str : unknown_str;
}

/*
 * Tries to match 'val' against each element in the value_string array 'vs'.
 * On a match, returns the associated string ptr, and sets "*idx" to the
 * index in that table.  On failure, returns NULL, and sets "*idx" to -1.
 */
const char*
try_val_to_str_idx( const unsigned int val, const value_string* vs, int* idx )
{
  int i = 0;

  assert( idx != NULL );

  if ( vs )
  {
    while ( vs[i].strptr )
    {
      if ( vs[i].value == val )
      {
        *idx = i;
        return vs[i].strptr;
      }
      ++i;
    }
  }

  *idx = -1;
  return NULL;
}

/* Like try_val_to_str_idx(), but doesn't return the index. */
const char*
try_val_to_str( const unsigned int val, const value_string* vs )
{
  int ignore_me;
  return try_val_to_str_idx( val, vs, &ignore_me );
}

static const value_string numbers_vals[] =
{
  { 0, "zero" },
  { 1, "one" },
  { 2, "two" },
  { 3, "three" },
  { 4, "four" },
  { 7, "seven" },
  { 8, "eight" },
  { 9, "nine" },
  { 0, NULL }
};

int main( void )
{
  int i;

  for ( i = 0; i < 10; ++i ) {
    printf( "%s\n", val_to_str( i, numbers_vals, "?" ) );
  }

  return 0;
}
\endcode

Refactoring it to mimic your example is left as an exercise for the
reader.

Best regards,
John D.

[toc] | [prev] | [next] | [standalone]


#91082

FromDavid Brown <david.brown@hesbynett.no>
Date2016-07-26 10:59 +0200
Message-ID<nn78qd$h3u$1@dont-email.me>
In reply to#91063
On 25/07/16 23:41, jadill33@gmail.com wrote:
> On Monday, July 25, 2016 at 12:42:00 PM UTC-4, Richard Heathfield wrote:
>> On 25/07/16 17:06, Richard Bos wrote:
>>> Richard Heathfield <r...@...uk> wrote:
>>>
<snip>
>>
>>> but it only works well if the accepted values of a are
>>> contiguous (or nearly so, with at most a handful of ugly extra defaults
>>> scattered through the array).
>>
>> That's right. I fitted the solution to the problem. If the problem 
>> changes, sometimes the solution changes too (for example, to a perfect 
>> hash or even some kind of dictionary).
> 
> I think I have you covered here.
> 
> \code
<snip linear search>
> \endcode
> 
> Refactoring it to mimic your example is left as an exercise for the
> reader.
> 

If the accepted values don't fit a nice pattern to allow a simple
solution such as Richard's, why not just use a switch?

static const char *get_foo(size_t a) {
	switch (a) {
		case 0 : return "zero";
		case 1 : return "one";
		case 2 : return "two";
		case 3 : return "three";
		default : return "four";
	}
}

Then the compiler can sort out the best arrangement of tables,
calculations, comparisons, etc.  If your set of values and strings is
big enough to warrant something smarter than such a switch, then it is
probably big enough to warrant something smarter than a linear search.
You would at least want a binary search, if not a hash of some sort (as
suggested by Richard).

[toc] | [prev] | [next] | [standalone]


#91132

Fromjadill33@gmail.com
Date2016-07-27 06:20 -0700
Message-ID<db999c15-dd8b-4dbe-9f55-936d56ca32c9@googlegroups.com>
In reply to#91082
On Tuesday, July 26, 2016 at 5:00:08 AM UTC-4, David Brown wrote:
> On 25/07/16 23:41, j...@...com wrote:
> > On Monday, July 25, 2016 at 12:42:00 PM UTC-4, Richard Heathfield wrote:
> >> On 25/07/16 17:06, Richard Bos wrote:
> >>> Richard Heathfield <r...@...uk> wrote:
> >>>
> <snip>
> >>
> >>> but it only works well if the accepted values of a are
> >>> contiguous (or nearly so, with at most a handful of ugly extra defaults
> >>> scattered through the array).
> >>
> >> That's right. I fitted the solution to the problem. If the problem 
> >> changes, sometimes the solution changes too (for example, to a perfect 
> >> hash or even some kind of dictionary).
> > 
> > I think I have you covered here.
> > 
> > \code
> <snip linear search>
> > \endcode
> > 
> > Refactoring it to mimic your example is left as an exercise for the
> > reader.
> > 
> 
> If the accepted values don't fit a nice pattern to allow a simple
> solution such as Richard's, why not just use a switch?

Depends on the scope of the problem.  If it's a one time translation in a
small embedded system, then a single switch is fine.  If you have to
translate lots of enumerated values to strings for human readability, as
you might find in a packet analyzer or a MIL-1553 traffic bus monitor,
then raw coding hundreds of these switch statements is not ideal.

> static const char *get_foo(size_t a) {
> 	switch (a) {
> 		case 0 : return "zero";
> 		case 1 : return "one";
> 		case 2 : return "two";
> 		case 3 : return "three";
> 		default : return "four";
> 	}
> }
> 
> Then the compiler can sort out the best arrangement of tables,
> calculations, comparisons, etc.  If your set of values and strings is
> big enough to warrant something smarter than such a switch, then it is
> probably big enough to warrant something smarter than a linear search.
> You would at least want a binary search, if not a hash of some sort (as
> suggested by Richard).

Most of the enumerated value to string tranlations that I have are small.
I just have a lot of them.  If I had a lot of large tables, then yes I
would consider making them more complex.  In my translations, the majority
of translations are simple binary conditions like "on/off", "true/false",
though there are some tables with a few dozen elements.  For those, I guess
I consider the increase in code complexity to not be worth the (potentially
imperceptible) decrease in efficiency.

Best regards,
John D.

[toc] | [prev] | [next] | [standalone]


#91134

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-07-27 15:44 +0100
Message-ID<87h9bbf8d7.fsf@bsb.me.uk>
In reply to#91132
jadill33@gmail.com writes:

> On Tuesday, July 26, 2016 at 5:00:08 AM UTC-4, David Brown wrote:
>> On 25/07/16 23:41, j...@...com wrote:
>> > On Monday, July 25, 2016 at 12:42:00 PM UTC-4, Richard Heathfield wrote:
>> >> On 25/07/16 17:06, Richard Bos wrote:
>> >>> Richard Heathfield <r...@...uk> wrote:
>> >>>
>> <snip>
>> >>
>> >>> but it only works well if the accepted values of a are
>> >>> contiguous (or nearly so, with at most a handful of ugly extra defaults
>> >>> scattered through the array).
>> >>
>> >> That's right. I fitted the solution to the problem. If the problem 
>> >> changes, sometimes the solution changes too (for example, to a perfect 
>> >> hash or even some kind of dictionary).
>> > 
>> > I think I have you covered here.
>> > 
>> > \code
>> <snip linear search>
>> > \endcode
>> > 
>> > Refactoring it to mimic your example is left as an exercise for the
>> > reader.
>> > 
>> 
>> If the accepted values don't fit a nice pattern to allow a simple
>> solution such as Richard's, why not just use a switch?
>
> Depends on the scope of the problem.  If it's a one time translation in a
> small embedded system, then a single switch is fine.  If you have to
> translate lots of enumerated values to strings for human readability, as
> you might find in a packet analyzer or a MIL-1553 traffic bus monitor,
> then raw coding hundreds of these switch statements is not ideal.
<snip>
> Most of the enumerated value to string tranlations that I have are small.
> I just have a lot of them.

Do you know about the X macro trick (it may have a proper name, but
that's what I call it)?  You can use it generate code for arbitrary
lists like this.  First, you put you enum into a file (list.h in this
case):

  X(red, 42)
  X(green, 34)
  X(blue, 12)

Here, I've allowed for the full generality with arbitrary numbers.  Now
you can define the enum like this:

  #define X(name, num) name = num,
  enum List {
  #include "list.h"
  };

and, elsewhere, you can generate the function to map values to strings
like this:

  const char *enum_to_str(unsigned int e)
  {
       switch (e) {
  #define X(name, num) case name: return #name;
  #include "list.h"
       }
       return "default";
  }

Of course, with consecutive values, you can use similar code to make a
table rather than a switch and the X macro list would just need the name
rather than a name and a value.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#91146

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-07-27 16:22 +0100
Message-ID<87zip3ds1d.fsf@bsb.me.uk>
In reply to#91134
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>Do you know about the X macro trick (it may have a proper name, but
>
>   Know? I /invented/ it!
<snip code>
>   Ok, I found this out by myself, but probably I am neither
>   the only nor the first one, who came up with this idea.

Yes, I think it's been invented dozens of times.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#91164

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2016-07-27 11:20 -0600
Message-ID<1binvrf16l.fsf@pfeifferfamily.net>
In reply to#91134
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>Do you know about the X macro trick (it may have a proper name, but
>
>   Know? I /invented/ it!
>
> /* 
> < filename  = [stringcall.c]
>   encoding  = [ANSI_X3.4-1968]
>   notation  = [ISO/IEC 9899:1999 (E)]
>   author    = [Stefan Ram] > */ 
> #include <stdio.h>  /* puts   */
> #include <string.h> /* strcmp */
> #define F(r,n,b) r n b
> #define FUNCTIONS \
> F( void, iota, (){ puts( "Lima" ); } )\
> F( void, zeta, (){ puts( "Zulu"  ); } )\
> /**/
> FUNCTIONS
> #undef F
> #define F(r,n,b) n,
> void( * const function[] )() ={ FUNCTIONS };
> #undef F
> #define F(r,n,b) #n,
> char const * const name[] ={ FUNCTIONS };
> #undef F
> int const top = sizeof name / sizeof 0[ name ];
> void call( char const * const n )
> { for( int i = 0; i < top; ++i )
>   if( !strcmp( n, i[ name ]))i[ function ](); }
> int main( void ){ call( "iota" ); call( "zeta" ); }
>
>   Ok, I found this out by myself, but probably I am neither
>   the only nor the first one, who came up with this idea.
>
>   Maybe one can do this with functions too?
>
> #include <stdio.h>
>
> void( *f )( char const *, int n );
>
> void g()
> { f( "alpha", 2 );
>   f( "beta",  4 ); }
>
> void putstring( char const * const text, int const n )
> { puts( text ); }
>
> void putnumber( char const * const text, int const n )
> { printf( "%d\n", n ); }
>
> int main( void )
> { f = putstring; g();
>   f = putnumber; g(); }
>
> alpha
> beta
> 2
> 4
>
>   See? Yet another invention of mine!
>
>   (I do not remember having seen this trick with functions
>   before, but probably ...)

I did pretty much the same thing for a program's configuration files
once.  I used a macro I called "process" that took information about a
data structure as its arguments.  One source file #defined process as
read_field, another as write_field.  Now my .h file could just "process"
all the fields in order, so any changes I made in the configuration file
format were automatically tracked both reading and writing it.

[toc] | [prev] | [next] | [standalone]


#91180

Fromluser droog <luser.droog@gmail.com>
Date2016-07-27 15:32 -0700
Message-ID<ed2cc33d-fe6d-4b69-92ac-41f542e06bb5@googlegroups.com>
In reply to#91134
On Wednesday, July 27, 2016 at 9:45:01 AM UTC-5, Ben Bacarisse wrote:
> jadill33@gmail.com writes:
> 
> > On Tuesday, July 26, 2016 at 5:00:08 AM UTC-4, David Brown wrote:
> >> On 25/07/16 23:41, j...@...com wrote:
> >> > On Monday, July 25, 2016 at 12:42:00 PM UTC-4, Richard Heathfield wrote:
> >> >> On 25/07/16 17:06, Richard Bos wrote:
> >> >>> Richard Heathfield <r...@...uk> wrote:
> >> >>>
> >> <snip>
> >> >>
> >> >>> but it only works well if the accepted values of a are
> >> >>> contiguous (or nearly so, with at most a handful of ugly extra defaults
> >> >>> scattered through the array).
> >> >>
> >> >> That's right. I fitted the solution to the problem. If the problem 
> >> >> changes, sometimes the solution changes too (for example, to a perfect 
> >> >> hash or even some kind of dictionary).
> >> > 
> >> > I think I have you covered here.
> >> > 
> >> > \code
> >> <snip linear search>
> >> > \endcode
> >> > 
> >> > Refactoring it to mimic your example is left as an exercise for the
> >> > reader.
> >> > 
> >> 
> >> If the accepted values don't fit a nice pattern to allow a simple
> >> solution such as Richard's, why not just use a switch?
> >
> > Depends on the scope of the problem.  If it's a one time translation in a
> > small embedded system, then a single switch is fine.  If you have to
> > translate lots of enumerated values to strings for human readability, as
> > you might find in a packet analyzer or a MIL-1553 traffic bus monitor,
> > then raw coding hundreds of these switch statements is not ideal.
> <snip>
> > Most of the enumerated value to string tranlations that I have are small.
> > I just have a lot of them.
> 
> Do you know about the X macro trick (it may have a proper name, but
> that's what I call it)?  You can use it generate code for arbitrary
> lists like this.  

I love X Macros! But let me show an alternate form that I think is nicer.

>First, you put you enum into a file (list.h in this
> case):
> 
>   X(red, 42)
>   X(green, 34)
>   X(blue, 12)
> 

The alternative is to put the list into a macro. For reasons to be 
elaborated later, the macro to call on each value `X` it itself
passed-in to this macro. 

#define MY_LIST(X) \
    X(red, 42) \
    X(green, 34) \
    X(blue, 12) \
    /**/

> Here, I've allowed for the full generality with arbitrary numbers.  Now
> you can define the enum like this:
> 
>   #define X(name, num) name = num,
>   enum List {
>   #include "list.h"
>   };
> 

For the alternative, rather than calling it `X` here, give it a meaningful
name.

#define DEFINE_ENUM_VALUES(name, num) name = num,
enum List {
    MY_LIST(DEFINE_ENUM_VALUES)
};

> and, elsewhere, you can generate the function to map values to strings
> like this:
> 
>   const char *enum_to_str(unsigned int e)
>   {
>        switch (e) {
>   #define X(name, num) case name: return #name;
>   #include "list.h"
>        }
>        return "default";
>   }

Same here. `X` can be a more meaningful name.

const char *enum_to_str(unsigned int e)
{
    switch (e) {
#define YIELD_STRING(name, num) case name: return #name;
        MY_LIST(YIELD_STRING)
    }
    return "default";
}

> Of course, with consecutive values, you can use similar code to make a
> table rather than a switch and the X macro list would just need the name
> rather than a name and a value.
> 

Ditto. Thanks for bringing this up!

[toc] | [prev] | [next] | [standalone]


#91230

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-07-28 14:47 +0100
Message-ID<8760rpzxgj.fsf@bsb.me.uk>
In reply to#91180
luser droog <luser.droog@gmail.com> writes:

> On Wednesday, July 27, 2016 at 9:45:01 AM UTC-5, Ben Bacarisse wrote:
>> jadill33@gmail.com writes:
<snip>
>> > Depends on the scope of the problem.  If it's a one time translation in a
>> > small embedded system, then a single switch is fine.  If you have to
>> > translate lots of enumerated values to strings for human readability, as
>> > you might find in a packet analyzer or a MIL-1553 traffic bus monitor,
>> > then raw coding hundreds of these switch statements is not ideal.
>> <snip>
>> > Most of the enumerated value to string tranlations that I have are small.
>> > I just have a lot of them.
>> 
>> Do you know about the X macro trick (it may have a proper name, but
>> that's what I call it)?  You can use it generate code for arbitrary
>> lists like this.  
>
> I love X Macros! But let me show an alternate form that I think is nicer.
>
>>First, you put you enum into a file (list.h in this
>> case):
>> 
>>   X(red, 42)
>>   X(green, 34)
>>   X(blue, 12)
>> 
>
> The alternative is to put the list into a macro. For reasons to be 
> elaborated later, the macro to call on each value `X` it itself
> passed-in to this macro. 
>
> #define MY_LIST(X) \
>     X(red, 42) \
>     X(green, 34) \
>     X(blue, 12) \
>     /**/

Yes, there's a lot to be said for doing it that way round (passing in a
macro name at expansion time), but when the lists are being
automatically generated it can be handy just to have them in a file to
#include.  Mind you, the extra line and trailing \s are not much bother
(provided you can generate a suitable name) so this way would work in
that situation too.

<snip>
> Ditto. Thanks for bringing this up!

You're welcome.  Thanks for expanding on it.  It's method worth knowing.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#91010

FromKeith Thompson <kst-u@mib.org>
Date2016-07-25 08:46 -0700
Message-ID<lnk2g9d8jy.fsf@kst-u.example.com>
In reply to#90965
jgh@mdfs.net writes:
> Keith Thompson wrote:
>> A better solution is:
>>     if      (a == 0) result = "zero";
>>     else if (a == 1) result = "one";
>>     else if (a == 2) result = "two";
>>     else if (a == 3) result = "three";
>>     else             result = "four";
>>     return result;
>
> If you want to do multiple ifs like that, I prefer to do:
>     result = "four";              // default
>     if (a == 0) result = "zero"; 
>     if (a == 1) result = "one";
>     if (a == 2) result = "two";
>     if (a == 3) result = "three";
>     return result;
>
> jgh

Why do you omit the "else"s?

Of course in this specific case a switch statement would be clearer
(and, less importantly, faster), but I presume the example is meant
as a more general illustration, covering cases where "switch" would
not work.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#91085

FromDavid Brown <david.brown@hesbynett.no>
Date2016-07-26 12:44 +0200
Message-ID<nn7ets$4t6$1@dont-email.me>
In reply to#91010
On 25/07/16 17:46, Keith Thompson wrote:
> jgh@mdfs.net writes:
>> Keith Thompson wrote:
>>> A better solution is:
>>>     if      (a == 0) result = "zero";
>>>     else if (a == 1) result = "one";
>>>     else if (a == 2) result = "two";
>>>     else if (a == 3) result = "three";
>>>     else             result = "four";
>>>     return result;
>>
>> If you want to do multiple ifs like that, I prefer to do:
>>     result = "four";              // default
>>     if (a == 0) result = "zero"; 
>>     if (a == 1) result = "one";
>>     if (a == 2) result = "two";
>>     if (a == 3) result = "three";
>>     return result;
>>
>> jgh
> 
> Why do you omit the "else"s?

Presumably the else's were omitted because they are not necessary, and
perhaps also because in many coding standards they would require
brackets to added.  The else's don't make the code any clearer to the
reader, and are unlikely to make any difference to a compiler's code
generation (assuming at least basic optimisation).

> 
> Of course in this specific case a switch statement would be clearer
> (and, less importantly, faster), but I presume the example is meant
> as a more general illustration, covering cases where "switch" would
> not work.
> 

[toc] | [prev] | [next] | [standalone]


#91089

FromKeith Thompson <kst-u@mib.org>
Date2016-07-26 08:24 -0700
Message-ID<lnh9bcbexi.fsf@kst-u.example.com>
In reply to#91085
David Brown <david.brown@hesbynett.no> writes:
> On 25/07/16 17:46, Keith Thompson wrote:
>> jgh@mdfs.net writes:
>>> Keith Thompson wrote:
>>>> A better solution is:
>>>>     if      (a == 0) result = "zero";
>>>>     else if (a == 1) result = "one";
>>>>     else if (a == 2) result = "two";
>>>>     else if (a == 3) result = "three";
>>>>     else             result = "four";
>>>>     return result;
>>>
>>> If you want to do multiple ifs like that, I prefer to do:
>>>     result = "four";              // default
>>>     if (a == 0) result = "zero"; 
>>>     if (a == 1) result = "one";
>>>     if (a == 2) result = "two";
>>>     if (a == 3) result = "three";
>>>     return result;
>>>
>>> jgh
>> 
>> Why do you omit the "else"s?
>
> Presumably the else's were omitted because they are not necessary, and
> perhaps also because in many coding standards they would require
> brackets to added.  The else's don't make the code any clearer to the
> reader, and are unlikely to make any difference to a compiler's code
> generation (assuming at least basic optimisation).

They might not be necessary in this particular case, but when I read the
code I have to verify that no more than one of the conditions can be
true.  In a more complicated example, that could be difficult.

I doubt that a coding standard would require curly braces with "else"
but not require them without it.  And if it did, the answer would be to
add the braces.

(In any case, thanks for your response, but I asked why jgh ommitted the
"else"s.)

>> Of course in this specific case a switch statement would be clearer
>> (and, less importantly, faster), but I presume the example is meant
>> as a more general illustration, covering cases where "switch" would
>> not work.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#91098

FromDavid Brown <david.brown@hesbynett.no>
Date2016-07-26 19:26 +0200
Message-ID<nn86fj$sip$1@dont-email.me>
In reply to#91089
On 26/07/16 17:24, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 25/07/16 17:46, Keith Thompson wrote:
>>> jgh@mdfs.net writes:
>>>> Keith Thompson wrote:
>>>>> A better solution is:
>>>>>     if      (a == 0) result = "zero";
>>>>>     else if (a == 1) result = "one";
>>>>>     else if (a == 2) result = "two";
>>>>>     else if (a == 3) result = "three";
>>>>>     else             result = "four";
>>>>>     return result;
>>>>
>>>> If you want to do multiple ifs like that, I prefer to do:
>>>>     result = "four";              // default
>>>>     if (a == 0) result = "zero"; 
>>>>     if (a == 1) result = "one";
>>>>     if (a == 2) result = "two";
>>>>     if (a == 3) result = "three";
>>>>     return result;
>>>>
>>>> jgh
>>>
>>> Why do you omit the "else"s?
>>
>> Presumably the else's were omitted because they are not necessary, and
>> perhaps also because in many coding standards they would require
>> brackets to added.  The else's don't make the code any clearer to the
>> reader, and are unlikely to make any difference to a compiler's code
>> generation (assuming at least basic optimisation).
> 
> They might not be necessary in this particular case, but when I read the
> code I have to verify that no more than one of the conditions can be
> true.  In a more complicated example, that could be difficult.

It all depends on the style of code you are used to.  But you are
certainly right that in a more complicated example, you would probably
want to structure the code a little differently.

> 
> I doubt that a coding standard would require curly braces with "else"
> but not require them without it.  And if it did, the answer would be to
> add the braces.

It is not unreasonable.  A coding standard could allow unbracketed
single-line if statements with a simple "then" clause (such as "if (a ==
0) result = "zero";) while insisting on brackets for multi-line
statements, complex statements, or else clauses.

> 
> (In any case, thanks for your response, but I asked why jgh ommitted the
> "else"s.)

Yes, of course - that will be up to him to respond.  I can only tell you
why /I/ might well omit the else's in such a code snippet.

> 
>>> Of course in this specific case a switch statement would be clearer
>>> (and, less importantly, faster), but I presume the example is meant
>>> as a more general illustration, covering cases where "switch" would
>>> not work.
> 

[toc] | [prev] | [next] | [standalone]


#91096

FromBartC <bc@freeuk.com>
Date2016-07-26 18:03 +0100
Message-ID<nn855l$nn4$1@dont-email.me>
In reply to#91085
On 26/07/2016 11:44, David Brown wrote:
> On 25/07/16 17:46, Keith Thompson wrote:
>> jgh@mdfs.net writes:
>>> Keith Thompson wrote:
>>>> A better solution is:
>>>>     if      (a == 0) result = "zero";
>>>>     else if (a == 1) result = "one";
>>>>     else if (a == 2) result = "two";
>>>>     else if (a == 3) result = "three";
>>>>     else             result = "four";
>>>>     return result;
>>>
>>> If you want to do multiple ifs like that, I prefer to do:
>>>     result = "four";              // default
>>>     if (a == 0) result = "zero";
>>>     if (a == 1) result = "one";
>>>     if (a == 2) result = "two";
>>>     if (a == 3) result = "three";
>>>     return result;
>>>
>>> jgh
>>
>> Why do you omit the "else"s?
>
> Presumably the else's were omitted because they are not necessary, and
> perhaps also because in many coding standards they would require
> brackets to added.  The else's don't make the code any clearer to the
> reader, and are unlikely to make any difference to a compiler's code
> generation (assuming at least basic optimisation).

It looks wrong.

The options are exclusive so they should be expressed that way, by using 
an if-else chain perhaps.

Otherwise the human reader needs to double-check that at most one option 
is executed, and so does the compiler.

(You shouldn't really rely on a compiler either to do the job of tidying 
up poor code like this. The clear intent of this code, as written, is to 
always evaluate four if-statements. I believe in a compiler doing what 
the programmer intended.)

This code might even lead to people posting on here as to why the 
expected else clauses are omitted!

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#90243

FromKen Brody <kenbrody@spamcop.net>
Date2016-07-11 19:15 -0400
Message-ID<nm19be$q6v$1@dont-email.me>
In reply to#90136
On 7/8/2016 5:46 PM, James Kuyper wrote:
> On 07/08/2016 01:03 PM, Gareth Owen wrote:
>> Keith Thompson <kst-u@mib.org> writes:
>>
>>> I would look forward to your explanation of how that makes any sense
>>> at all (preferably, as Richard suggests, in a different thread)
>>> if I thought there was a reasonable chance of that happening.
>>
>> Well if thought "structured" meant "SESE in all circumstances", and your
>> program had at least one failure mode and one success mode you'd store
>> your return value in a variable and return it in the sole return-statement.
>
> One of my first significant programming projects involved trying to make
> a minor change to a text-based computer game written in spaghetti Basic,
> that was deliberately padded to come out to exactly 1000 lines of code.
> My first paid programming job involved unraveling a big ball of
> spaghetti Fortran code.
[...]

Speaking of BASIC and FORTRAN...

One of my first significant programming projects was to rewrite a rather 
hefty Star Trek program written in FORTRAN into a rather wimpy version of 
BASIC.  (Why? Because that's the only language that my high school had 
available "way back when".)

-- 
Kenneth Brody

[toc] | [prev] | [next] | [standalone]


#90245

Fromsupercat@casperkitty.com
Date2016-07-11 16:46 -0700
Message-ID<76a61972-7163-4711-a325-000287eeeb21@googlegroups.com>
In reply to#90243
On Monday, July 11, 2016 at 6:16:06 PM UTC-5, Ken Brody wrote:
> One of my first significant programming projects was to rewrite a rather 
> hefty Star Trek program written in FORTRAN into a rather wimpy version of 
> BASIC.  (Why? Because that's the only language that my high school had 
> available "way back when".)

Did you know that the game was ported to the Atari 2600 Video Computer
System in 1980?  The lack of floating-point support meant one could only
move or fire in eight directions, and the ratings at the end failed to
consider initial mission parameters so eking out a victory when given a
huge number of enemies and minimal resources would be rewarded with a
poor rating, while coasting through on an easy mission with more generous
resources would yield a better one.  Aside from those details, though,
the game is pretty much there.

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web