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


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

arranging items in a array with a sorted pointer-list

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2020-11-28 11:00 +0100
Last post2020-11-30 09:10 +0000
Articles 20 on this page of 74 — 19 participants

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


Contents

  arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-28 11:00 +0100
    Re: arranging items in a array with a sorted pointer-list Melzzzzz <Melzzzzz@zzzzz.com> - 2020-11-28 10:49 +0000
      Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-28 12:12 +0100
    Re: arranging items in a array with a sorted pointer-list Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-11-28 03:21 -0800
      Re: arranging items in a array with a sorted pointer-list Richard Damon <Richard@Damon-Family.org> - 2020-11-28 08:32 -0500
        Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-28 14:49 +0100
          Re: arranging items in a array with a sorted pointer-list scott@slp53.sl.home (Scott Lurndal) - 2020-11-28 16:08 +0000
            Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-28 17:16 +0100
            Re: arranging items in a array with a sorted pointer-list Bart <bc@freeuk.com> - 2020-11-28 16:23 +0000
              Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-28 17:35 +0100
    Re: arranging items in a array with a sorted pointer-list "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2020-11-28 17:34 +0100
      Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-28 17:38 +0100
        Re: arranging items in a array with a sorted pointer-list Richard Damon <Richard@Damon-Family.org> - 2020-11-28 13:03 -0500
          Re: arranging items in a array with a sorted pointer-list Tim Woodall <news001@woodall.me.uk> - 2020-11-28 23:40 +0000
        Re: arranging items in a array with a sorted pointer-list Dolores Filandro <dolfiland8@gmail.com> - 2020-12-23 13:06 -0800
    Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-11-28 18:08 +0000
      Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-28 19:14 +0100
        Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-11-28 19:14 +0000
    Re: arranging items in a array with a sorted pointer-list Tim Woodall <news001@woodall.me.uk> - 2020-11-28 18:13 +0000
    Re: arranging items in a array with a sorted pointer-list Siri Cruise <chine.bleu@yahoo.com> - 2020-11-28 17:16 -0800
      Re: arranging items in a array with a sorted pointer-list Juha Nieminen <nospam@thanks.invalid> - 2020-11-29 09:41 +0000
        Re: arranging items in a array with a sorted pointer-list Siri Cruise <chine.bleu@yahoo.com> - 2020-11-29 02:16 -0800
          Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-11-29 18:32 +0000
          Re: arranging items in a array with a sorted pointer-list Juha Nieminen <nospam@thanks.invalid> - 2020-11-30 09:01 +0000
            Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-11-30 13:03 +0000
              Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-11-30 20:46 +0000
                Re: arranging items in a array with a sorted pointer-list scott@slp53.sl.home (Scott Lurndal) - 2020-11-30 21:03 +0000
                  Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-11-30 22:27 +0000
                    Re: arranging items in a array with a sorted pointer-list Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2020-11-30 18:14 -0700
                      Re: arranging items in a array with a sorted pointer-list James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-11-30 23:02 -0500
                      Re: arranging items in a array with a sorted pointer-list Dolores Filandro <dolfiland8@gmail.com> - 2020-11-30 20:12 -0800
                        Re: arranging items in a array with a sorted pointer-list scott@slp53.sl.home (Scott Lurndal) - 2020-12-01 15:04 +0000
                          Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-01 22:10 +0000
                            Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-01 22:25 +0000
                              Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-01 23:43 +0000
                            Re: arranging items in a array with a sorted pointer-list James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-12-01 23:25 -0500
                              Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-02 14:53 +0000
                                Re: arranging items in a array with a sorted pointer-list Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-02 07:03 -0800
                                  Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-02 23:48 +0000
                                Re: arranging items in a array with a sorted pointer-list James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-12-02 11:13 -0500
                                  Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 05:34 -0800
                                Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-02 16:25 +0000
                                  Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-02 23:58 +0000
                                Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-03 21:16 -0800
                      Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-01 07:33 +0000
                        Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-01 03:46 -0800
                          Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-01 17:15 +0000
                            Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-04 00:17 -0800
                          Re: arranging items in a array with a sorted pointer-list Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-01 10:07 -0800
                            Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-13 11:06 -0800
                        Re: arranging items in a array with a sorted pointer-list Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-01 07:04 -0800
                      Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-01 04:09 -0800
        Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-11-29 18:28 +0000
          Re: arranging items in a array with a sorted pointer-list dave_thompson_2@comcast.net - 2021-01-31 16:03 -0500
        Re: arranging items in a array with a sorted pointer-list Richard Damon <Richard@Damon-Family.org> - 2020-11-29 14:01 -0500
          Re: arranging items in a array with a sorted pointer-list Juha Nieminen <nospam@thanks.invalid> - 2020-11-30 09:05 +0000
            Re: arranging items in a array with a sorted pointer-list Richard Damon <Richard@Damon-Family.org> - 2020-11-30 07:09 -0500
            Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-11-30 13:06 +0000
              Re: arranging items in a array with a sorted pointer-list Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-11-30 06:28 -0800
                Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-11-30 15:50 +0000
              Re: arranging items in a array with a sorted pointer-list James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-11-30 10:07 -0500
                Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-11-30 15:26 +0000
            Re: arranging items in a array with a sorted pointer-list James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-11-30 10:02 -0500
      Re: arranging items in a array with a sorted pointer-list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-11-29 12:32 +0000
        Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-11-29 18:58 -0800
      Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-29 13:52 +0100
        Re: arranging items in a array with a sorted pointer-list Dolores Filandro <dolfiland8@gmail.com> - 2020-12-23 13:56 -0800
    Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-11-28 23:41 -0800
      Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-05 12:23 +0100
        Re: arranging items in a array with a sorted pointer-list Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 16:27 -0800
          Re: arranging items in a array with a sorted pointer-list David Brown <david.brown@hesbynett.no> - 2020-12-07 11:17 +0100
    Re: arranging items in a array with a sorted pointer-list Kaz Kylheku <563-365-8930@kylheku.com> - 2020-11-29 18:34 +0000
      Re: arranging items in a array with a sorted pointer-list Bonita Montero <Bonita.Montero@gmail.com> - 2020-11-29 21:23 +0100
      Re: arranging items in a array with a sorted pointer-list Juha Nieminen <nospam@thanks.invalid> - 2020-11-30 09:10 +0000

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


#156973

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-12-06 05:34 -0800
Message-ID<86blf7kqi8.fsf@linuxsc.com>
In reply to#156865
James Kuyper <jameskuyper@alumni.caltech.edu> writes:

> On 12/2/20 9:53 AM, Ben Bacarisse wrote:
>
>> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
>
> ...
>
>>> I'm pretty tired right now, so maybe I'm missing something
>>> obvious.  If written in C, how would bsearch() go about returning
>>> a void* when it's arguments are const void*, without casting away
>>> const somewhere?

In English, the possessive form of "it" is spelled "its", with no
apostrophe.  The word "it's" is a contraction for "it is".

>> There are various ways, but as an old-timer,
>
> I definitely qualify as an old-time;  I remember what C was like
> before prototypes were added to the language.  They were an enormous
> improvement.

No one is suggesting otherwise.

>>  I like 
>>
>>   void *remove_const(s) void *s; { return s; }
>>
>> and in bsearch
>>
>>   return remove_const(ptr);
>
> I definitely don't like leaving out a function prototype,
> particularly when the only reason for doing so is to disable
> the type checking enabled by the prototype.

Here that isn't the only reason for not using a prototype, nor
even the most important reason.  A key point of not using a
prototype is so the call will have defined behavior.

However, if someone is determined never to use functions whose
declarations lack prototypes, that restriction too can be
accommodated:

  (file dequalify.h)

        #ifndef HAVE_DEQUALIFY_dot_H
        #define HAVE_DEQUALIFY_dot_H

        extern   void * dequalify( const volatile void * );

        #endif/*HAVE_DEQUALIFY_dot_H*/


  (file dequalify.c)

        #include "dequalify.h"

        #include <stdarg.h>

        static inline void *
        fixit( void *f( const volatile void * ), ... ){
            va_list a;  void *pv;

            va_start( a, f ),  pv = va_arg( a, void * ),  va_end( a );
            return  pv;
        }

        void *
        dequalify( const volatile void *x ){
            return  fixit( dequalify, x );
        }

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


#156866

FromKaz Kylheku <563-365-8930@kylheku.com>
Date2020-12-02 16:25 +0000
Message-ID<20201202081639.621@kylheku.com>
In reply to#156863
On 2020-12-02, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
>
>> On 12/1/20 5:10 PM, Ben Bacarisse wrote:
>>> scott@slp53.sl.home (Scott Lurndal) writes:
>>> 
>>>> Dolores Filandro <dolfiland8@gmail.com> writes:
>> ...
>>>>> You need to throw const away with a cast
>>>>> if you want to write the bsearch function in C.
>> ...
>>> bsearch's prototype includes const everywhere one might expect.
>>
>>     void *bsearch(const void *key, const void *base,
>>          size_t nmemb, size_t size,
>>          int (*compar)(const void *, const void *));
>>
>>> There's
>>> no apparent reason you'd have to cast away const to implement it.
>>> Dolores Filandro is, quite likely, trolling.
>>
>> I'm pretty tired right now, so maybe I'm missing something obvious. If
>> written in C, how would bsearch() go about returning a void* when it's
>> arguments are const void*, without casting away const somewhere?
>
> There are various ways, but as an old-timer, I like
>
>   void *remove_const(s) void *s; { return s; }
>
> and in bsearch
>
>   return remove_const(ptr);

That looks like UB. The function call requires the function's
parameter to be "const void *".

I.e. from a "legal" perspective, this is the same mistake as:

  func(arg)
  double arg;
  {
  }

  func(3);  /* undiagnosed int/double type mismatch */

A C dialect which makes it impossible to strip const qualifiers in
conversions would likely be coming from people who frown upon
subterfuges like this, and go out of their way to document them out.

-- 
TXR Programming Language: http://nongnu.org/txr
Music DIY Mailing List:  http://www.kylheku.com/diy
ADA MP-1 Mailing List:   http://www.kylheku.com/mp1

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


#156884

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-12-02 23:58 +0000
Message-ID<87360nwyj4.fsf@bsb.me.uk>
In reply to#156866
Kaz Kylheku <563-365-8930@kylheku.com> writes:

> On 2020-12-02, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
>>
>>> On 12/1/20 5:10 PM, Ben Bacarisse wrote:
>>>> scott@slp53.sl.home (Scott Lurndal) writes:
>>>> 
>>>>> Dolores Filandro <dolfiland8@gmail.com> writes:
>>> ...
>>>>>> You need to throw const away with a cast
>>>>>> if you want to write the bsearch function in C.
>>> ...
>>>> bsearch's prototype includes const everywhere one might expect.
>>>
>>>     void *bsearch(const void *key, const void *base,
>>>          size_t nmemb, size_t size,
>>>          int (*compar)(const void *, const void *));
>>>
>>>> There's
>>>> no apparent reason you'd have to cast away const to implement it.
>>>> Dolores Filandro is, quite likely, trolling.
>>>
>>> I'm pretty tired right now, so maybe I'm missing something obvious. If
>>> written in C, how would bsearch() go about returning a void* when it's
>>> arguments are const void*, without casting away const somewhere?
>>
>> There are various ways, but as an old-timer, I like
>>
>>   void *remove_const(s) void *s; { return s; }
>>
>> and in bsearch
>>
>>   return remove_const(ptr);
>
> That looks like UB. The function call requires the function's
> parameter to be "const void *".

No, there is a specific dispensation for this.

> I.e. from a "legal" perspective, this is the same mistake as:
>
>   func(arg)
>   double arg;
>   {
>   }
>
>   func(3);  /* undiagnosed int/double type mismatch */

No, this is a different case, and is indeed UB.

> A C dialect which makes it impossible to strip const qualifiers in
> conversions would likely be coming from people who frown upon
> subterfuges like this, and go out of their way to document them out.

Oh sure, but I'm treating this like a game though.  Thinking it through
properly seems a bit too much like work.

-- 
Ben.

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


#156903

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-12-03 21:16 -0800
Message-ID<864kl2nob7.fsf@linuxsc.com>
In reply to#156863
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> James Kuyper <jameskuyper@alumni.caltech.edu> writes:

[...]

>> If written in C, how would bsearch() go about returning a void*
>> when it's arguments are const void*, without casting away const
>> somewhere?
>
> There are various ways, but as an old-timer, I like
>
>   void *remove_const(s) void *s; { return s; }
>
> and in bsearch
>
>   return remove_const(ptr);

Thank you for this.  Very nice.

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


#156841

FromKaz Kylheku <563-365-8930@kylheku.com>
Date2020-12-01 07:33 +0000
Message-ID<20201130174257.91@kylheku.com>
In reply to#156838
On 2020-12-01, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote:
> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>
>> It can be the case that at the time the cast is written, there is no
>> const qualifier being cast away. The accident occurs when someone
>> later introduces const, and that cast now silently subverts it.
>
> Raising a question -- what would have been the downside (note that I'm
> recognizing it's Too Late, just Monday morning quarterbacking), when
> const was added to the language, to defining the cast so it doesn't
> throw the const away?
>
> ie if you had a
>
>     const int x;
>     
> and cast it with
>     (char) x
>
> having x then treated as type
>
>     const char
>
> My immediate intuition is that there is no case in which one would want
> to throw a const away with a cast, and this would have been a better
> choice.
>
> Thoughts?

I think that it would be a good choice for C++ or a C dialect
inspired by C++, in which there are overloaded functions and other
features.

jhere is the problem that the current function

  char *strchr(const char *str, int ch);

could not be written in that dialect. But let's think about it
from the perspective of adding this to a C dialect which is like
ANSI C, and has no const. Suppose we already have this, as a given:

  char *strchr(char *str, int ch);

This can't be used with const-qualified strings in our new
dialect, since const char * will not convert to char *, period.
We can introduce a separate function:

  const char *cstchr(const char *str, int ch);

But in C++, the <cstring> header has the nice solution due to function
overloading, which allows these functions to share the same name:

  const char *strchr(const char *str, int ch);
  char *strchr(char *str, int ch);

Writing duplicate functions which are almost identical, and have
different names, will quickly become irksome.

Other difficulties arise in C, like in situations where we have a
container that stores "void *" items, and would like to store
const-qualified pointers into it.  A union { void *p; const void *cp; }
could be used and the container could have a type field which indicates
whether it is the const kind of container or not. That feels somewhat
less than adequate; for all the fussing around, we end up relying on
run-time enforcement.  We could duplicate the container, or use some
preprocessor macros and whatnot.  C++ can pull a template in this
situation, and the problem is solved (or perhaps replaced by other
problems, at least).

Yet C++, in spite of being able to deal with situations like these
without stripping const, has const_cast! The likely reason for that is
that const_cast is needed for completeness: so that every kind of old
style cast can be converted to new style. Since old style already
exists, if it has any use cases that don't map to a combination of new
style casts, programmers will just use the old style cast.

-- 
TXR Programming Language: http://nongnu.org/txr
Music DIY Mailing List:  http://www.kylheku.com/diy
ADA MP-1 Mailing List:   http://www.kylheku.com/mp1

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


#156843

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-12-01 03:46 -0800
Message-ID<86y2ihoijs.fsf@linuxsc.com>
In reply to#156841
Kaz Kylheku <563-365-8930@kylheku.com> writes:

> On 2020-12-01, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote:
>
>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>
>>> It can be the case that at the time the cast is written, there is no
>>> const qualifier being cast away.  The accident occurs when someone
>>> later introduces const, and that cast now silently subverts it.
>>
>> Raising a question -- what would have been the downside (note that I'm
>> recognizing it's Too Late, just Monday morning quarterbacking), when
>> const was added to the language, to defining the cast so it doesn't
>> throw the const away?
>>
>> ie if you had a
>>
>>     const int x;
>>
>> and cast it with
>>     (char) x
>>
>> having x then treated as type
>>
>>     const char
>>
>> My immediate intuition is that there is no case in which one would want
>> to throw a const away with a cast, and this would have been a better
>> choice.
>>
>> Thoughts?
>
> I think that it would be a good choice for C++ or a C dialect
> inspired by C++, in which there are overloaded functions and other
> features.
>
> jhere is the problem that the current function
>
>   char *strchr(const char *str, int ch);
>
> could not be written in that dialect.  [...]

Think again.  Yes it could.

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


#156850

FromKaz Kylheku <563-365-8930@kylheku.com>
Date2020-12-01 17:15 +0000
Message-ID<20201201081946.308@kylheku.com>
In reply to#156843
On 2020-12-01, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>
>> On 2020-12-01, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote:
>>
>>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>>
>>>> It can be the case that at the time the cast is written, there is no
>>>> const qualifier being cast away.  The accident occurs when someone
>>>> later introduces const, and that cast now silently subverts it.
>>>
>>> Raising a question -- what would have been the downside (note that I'm
>>> recognizing it's Too Late, just Monday morning quarterbacking), when
>>> const was added to the language, to defining the cast so it doesn't
>>> throw the const away?
>>>
>>> ie if you had a
>>>
>>>     const int x;
>>>
>>> and cast it with
>>>     (char) x
>>>
>>> having x then treated as type
>>>
>>>     const char
>>>
>>> My immediate intuition is that there is no case in which one would want
>>> to throw a const away with a cast, and this would have been a better
>>> choice.
>>>
>>> Thoughts?
>>
>> I think that it would be a good choice for C++ or a C dialect
>> inspired by C++, in which there are overloaded functions and other
>> features.
>>
>> jhere is the problem that the current function
>>
>>   char *strchr(const char *str, int ch);
>>
>> could not be written in that dialect.  [...]
>
> Think again.  Yes it could.

I don't see how it could be written in strictly-conforming code, as it
can be now, without doing anything where the requirements are not
defined, or at least unspecified or implementation-defined.

I'm excluding possibilities such as:

  char *strchr(const char *str, int ch)
  {
     union { char *y; const char *x; } u;

     u.x = str;
     return strchr_impl(u.y, ch);
  }

I've thought about the memcpy hole:

  char *strchr(const char *str, int ch)
  {
     char *uqstr;

     memcpy(&uqstr, &str, sizeof uqstr);
     return strchr_impl(uqsr, ch);
  }

In the memcpy call, the address of str is const char **, and that
converts to the required const void *.  But does it? Arguably, that
conversion should arguably be banned under this dialect. Reason being:
it should be stipulated that pointer conversions must preserve const at
the same level of indirection.  It can't just be that if the destination
type has a const in it somewhere in he type tree, it's okay.

I'm thinking in the context that goal of this dialect is to make it
impossible to obtain a non-const-qualified pointer to any part of an
object, given a const-qualified pointer to it, without doing anything
erroneous or non-portable, where the requirements are not fastidiously
well-defined.

In that spirit, a conversion sequence like const char * -> intptr_t
would also not be allowed in this dialect, because the const qualifier
on the pointer must be preserved, and has nowhere to land in the target
type, which has no matching indirection level.


-- 
TXR Programming Language: http://nongnu.org/txr
Music DIY Mailing List:  http://www.kylheku.com/diy
ADA MP-1 Mailing List:   http://www.kylheku.com/mp1

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


#156909

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-12-04 00:17 -0800
Message-ID<86im9im1df.fsf@linuxsc.com>
In reply to#156850
Kaz Kylheku <563-365-8930@kylheku.com> writes:

> On 2020-12-01, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>
>>> On 2020-12-01, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote:
>>>
>>>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>>>
>>>>> It can be the case that at the time the cast is written, there is no
>>>>> const qualifier being cast away.  The accident occurs when someone
>>>>> later introduces const, and that cast now silently subverts it.
>>>>
>>>> Raising a question -- what would have been the downside (note that I'm
>>>> recognizing it's Too Late, just Monday morning quarterbacking), when
>>>> const was added to the language, to defining the cast so it doesn't
>>>> throw the const away?
>>>>
>>>> ie if you had a
>>>>
>>>>     const int x;
>>>>
>>>> and cast it with
>>>>     (char) x
>>>>
>>>> having x then treated as type
>>>>
>>>>     const char
>>>>
>>>> My immediate intuition is that there is no case in which one would want
>>>> to throw a const away with a cast, and this would have been a better
>>>> choice.
>>>>
>>>> Thoughts?
>>>
>>> I think that it would be a good choice for C++ or a C dialect
>>> inspired by C++, in which there are overloaded functions and other
>>> features.
>>>
>>> jhere is the problem that the current function
>>>
>>>   char *strchr(const char *str, int ch);
>>>
>>> could not be written in that dialect.  [...]
>>
>> Think again.  Yes it could.
>
> I don't see how it could be written in strictly-conforming code, as
> it can be now, without doing anything where the requirements are not
> defined, or at least unspecified or implementation-defined.

(In English usage, there is no hyphen between the adverb
"strictly" and the adjective "conforming".)

> I'm excluding possibilities such as:
>
>   char *strchr(const char *str, int ch)
>   {
>      union { char *y; const char *x; } u;
>
>      u.x = str;
>      return strchr_impl(u.y, ch);
>   }

There is no reason to exclude it.  The behavior is well defined,
and it produces the right result without having to depend on
behavior that is unspecified or implementation defined.

> I've thought about the memcpy hole:
>
>   char *strchr(const char *str, int ch)
>   {
>      char *uqstr;
>
>      memcpy(&uqstr, &str, sizeof uqstr);
>      return strchr_impl(uqsr, ch);
>   }
>
> In the memcpy call, the address of str is const char **, and that
> converts to the required const void *.  But does it?  Arguably, that
> conversion should arguably be banned under this dialect.  Reason being:
> it should be stipulated that pointer conversions must preserve const at
> the same level of indirection.  It can't just be that if the destination
> type has a const in it somewhere in he type tree, it's okay.
>
> I'm thinking in the context that goal of this dialect is to make it
> impossible to obtain a non-const-qualified pointer to any part of an
> object, given a const-qualified pointer to it, without doing anything
> erroneous or non-portable, where the requirements are not fastidiously
> well-defined.
>
> In that spirit, a conversion sequence like const char * -> intptr_t
> would also not be allowed in this dialect, because the const qualifier
> on the pointer must be preserved, and has nowhere to land in the target
> type, which has no matching indirection level.

I see.  I had thought you wanted to make a comment about C
except with a different rule for casting.  I see now that it was
just a lead-in to an exciting game of Calvinball.

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


#156852

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-12-01 10:07 -0800
Message-ID<871rg9o0x3.fsf@nosuchdomain.example.com>
In reply to#156843
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>> On 2020-12-01, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote:
>>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>>> It can be the case that at the time the cast is written, there is no
>>>> const qualifier being cast away.  The accident occurs when someone
>>>> later introduces const, and that cast now silently subverts it.
>>>
>>> Raising a question -- what would have been the downside (note that I'm
>>> recognizing it's Too Late, just Monday morning quarterbacking), when
>>> const was added to the language, to defining the cast so it doesn't
>>> throw the const away?
[...]
>> I think that it would be a good choice for C++ or a C dialect
>> inspired by C++, in which there are overloaded functions and other
>> features.
>>
>> jhere is the problem that the current function
>>
>>   char *strchr(const char *str, int ch);
>>
>> could not be written in that dialect.  [...]
>
> Think again.  Yes it could.

You have a habit of (it seems) deliberately withholding information
by alluding to some idea and expecting others to do the research
to reinforce your conclusions.  I find it annoying.  Does anyone
else find it at all useful?

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

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


#157254

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-12-13 11:06 -0800
Message-ID<86v9d5zfsf.fsf@linuxsc.com>
In reply to#156852
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>
>>> On 2020-12-01, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote:
>>>
>>>> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>>>>
>>>>> It can be the case that at the time the cast is written, there is no
>>>>> const qualifier being cast away.  The accident occurs when someone
>>>>> later introduces const, and that cast now silently subverts it.
>>>>
>>>> Raising a question -- what would have been the downside (note that I'm
>>>> recognizing it's Too Late, just Monday morning quarterbacking), when
>>>> const was added to the language, to defining the cast so it doesn't
>>>> throw the const away?
>
> [...]
>
>>> I think that it would be a good choice for C++ or a C dialect
>>> inspired by C++, in which there are overloaded functions and other
>>> features.
>>>
>>> jhere is the problem that the current function
>>>
>>>   char *strchr(const char *str, int ch);
>>>
>>> could not be written in that dialect.  [...]
>>
>> Think again.  Yes it could.
>
> You have a habit of (it seems) deliberately withholding information
> by alluding to some idea and expecting others to do the research
> to reinforce your conclusions.  I find it annoying.  Does anyone
> else find it at all useful?

There are a lot of different factors that go into deciding what
to say when I post.  Let me go through some recent examples.

In a thread about how to rearrange elements of an array, I posted
that I had a short function to do it but did not post the
function.  Because no algorithm had been posted, someone else
following up to my posting thought about the problem and posted a
solution that was a nice improvement over my own.

In a thread about changing the semantics of pointer casts so
'const' would be preserved, I posted a comment about several
points, but notably including a statement about being able to
provide a const-preserving cast using _Generic.  My post included
a short example of how to do that.

In this very thread, I implied that a const-removing conversion
could be accomplished but didn't say how.  Discussion following
that comment turned up several different was of thinking about
how a const-removing conversion might be effect, including a very
nice technique from Ben Bacarisse.  Of course I don't know for
sure but I suspect the discussion would not have been as diverse
if I had simply stated one way right at the outset.

In each of those cases I'm happy with the outcome, and I think other
people reading the thread probably benefited from my choice, even if
the OP being responded to didn't feel that way.  Those sorts of
considerations aren't always obvious.  Note also that not providing
information is not the same as withholding it - I might choose not
to say much at the start of a conversation and then say more later,
depending on which way the discussion goes.

Let me ask you about a case that has come up just today.  Looking
over the programs posted to solve the decommenting exercise, there
was one that showed surprising behavior, and I ended up tracking
down several defects in the code.  Now having this information, what
should I do about it?  Should I

  * post nothing at all?

  * post a statement saying the code has problems but not
    say anything about what the problems are?

  * show some test cases that evoke bad output?

  * identify a particular function where the problems are
    but not say any more than that?

  * say what the problems are but not more than that?

  * post revised code that fixes the problems?

It isn't obvious to me which of these choices (and the list is not
exhaustive) is the best choice overall for all concerned, including
readers other than the poster whose code is involved.  I think
different people would prefer different choices.  What's a good
choice for what to do here?  I'm interested to hear your assessment.

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


#156847

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-12-01 07:04 -0800
Message-ID<97809358-027d-4a28-8642-72048c44d7b7n@googlegroups.com>
In reply to#156841
On Tuesday, 1 December 2020 at 07:34:17 UTC, Kaz Kylheku wrote:
> 
> Other difficulties arise in C, like in situations where we have a 
> container that stores "void *" items, and would like to store 
> const-qualified pointers into it. A union { void *p; const void *cp; } 
> could be used and the container could have a type field which indicates 
> whether it is the const kind of container or not. That feels somewhat 
> less than adequate; for all the fussing around, we end up relying on 
> run-time enforcement. 
>
Often you want a callback, with a context pointer passed back to avoid 
the requirement for global variables.
The context pointer will often be logically constant because the 
callback doesn't change its own state. However for flexibility, it
needs to be a plain void *.

In C++ you don't need callbacks so much because you have other
mechanisms.

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


#156844

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-12-01 04:09 -0800
Message-ID<86tut5ohhh.fsf@linuxsc.com>
In reply to#156838
Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes:

> Kaz Kylheku <563-365-8930@kylheku.com> writes:
>
>> It can be the case that at the time the cast is written, there is no
>> const qualifier being cast away.  The accident occurs when someone
>> later introduces const, and that cast now silently subverts it.
>
> Raising a question -- what would have been the downside (note that I'm
> recognizing it's Too Late, just Monday morning quarterbacking), when
> const was added to the language, to defining the cast so it doesn't
> throw the const away?
>
> ie if you had a
>
>     const int x;
>
> and cast it with
>     (char) x
>
> having x then treated as type
>
>     const char
>
> My immediate intuition is that there is no case in which one would want
> to throw a const away with a cast, and this would have been a better
> choice.
>
> Thoughts?

1. Presumably you mean it for pointer types, so a (T*) cast of a
   (const X*) value would result in a (const T*) value.  There is
   effectively no difference between (char) x and (const char) x.

2. It violates the Law of Least Astonishment.

3. There are cases where throwing away 'const' at the start of a
   pointer type is useful.  Functions in the standard library do
   it;  as it happens I ran into a case recently where casting
   away 'const' from a pointer type looks like a good way to
   handle something that came up in code I am working on.

4. If someone wants a const-preserving pointer cast, it can be
   done in C11 and later, using _Generic:


        #define CONST_PRESERVING_CAST( T, p ) (         \
            _Generic( 0 ? (p) : (void*) (p),            \
                const void * : (const T)(p),            \
                      void * : (T)(p)                   \
            )                                           \
        )

        void
        example(){
            const int ci;
            int *p = CONST_PRESERVING_CAST( int *, &ci );
            // Produces an error.  To fix the error,
            // either remove 'const' from 'ci' type,
            // or add 'const' to start of 'p' type.
        }

I admit the macro isn't perfect, but it should be possible to
adapt it to other use cases where those may be important.

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


#156812

FromKaz Kylheku <563-365-8930@kylheku.com>
Date2020-11-29 18:28 +0000
Message-ID<20201129101416.481@kylheku.com>
In reply to#156803
On 2020-11-29, Juha Nieminen <nospam@thanks.invalid> wrote:
> In comp.lang.c++ Siri Cruise <chine.bleu@yahoo.com> wrote:
>> This is my code
>> 
>>     int stringcompare ( /*String comparison for qsort.*/
>>         const ptr a, const ptr b
>>     ) {
>>         char **A = a, **B = b;
>>         return strcmp(*A, *B);
>>     }
>
> Ah, I love how in C you just implicitly cast from const void* to
> non-const char** without a worry in the world, happily ignoring
> the compiler warnings, because what does the compiler know anyway?
> It's just a dumb program.

Arguably, you can do this in Your Compiler's C, not in ISO C.  The
diagnostic is required by ISO C, which requires no such implicit cast to
be performed.  The program is not required to successfully translate at
all.

> Also love how the comparator function is non-static, throwing it in the
> global namespace. Better not have any other function with that name
> anywhere else. But how likely is that? After all, "stringcompare" is
> such a unique name. The chances that anybody will ever use that same
> name anywhere are astronomically minuscule.

In fact, stringcompare intrudes into a namespace reserved by ISO C.
Programs which introduce external names beginning with "str" invoke
undefined behavior.

This is given in the "Future library directions" section.

"Function names that begin with str, mem, or wcs and a lowercase letter
may be added to the declarations in the <string.h> header."

In practice, this doesn't happen just in the future; implementors
add their own functions, like strdup (POSIX), strcasecmp (various?),
memchr (GNU) ...

If <string.h> is included, there are additional considerations in the
use of those names, because <string.h> can introduce macros beginning
with str. So this is required:

  #include <string.h>

  #undef stringcompare
  static int stringcompare(...)
  {
    ...
  }

-- 
TXR Programming Language: http://nongnu.org/txr
Music DIY Mailing List:  http://www.kylheku.com/diy
ADA MP-1 Mailing List:   http://www.kylheku.com/mp1

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


#158823

Fromdave_thompson_2@comcast.net
Date2021-01-31 16:03 -0500
Message-ID<1m6e1g9m3e9er2b1745s1nci3vmvn9oqvg@4ax.com>
In reply to#156812
(Sorry for delay, I didn't notice this got stuck in my newsreader.)

On Sun, 29 Nov 2020 18:28:37 +0000 (UTC), Kaz Kylheku
<563-365-8930@kylheku.com> wrote:
<snip>
> In fact, stringcompare intrudes into a namespace reserved by ISO C.
> Programs which introduce external names beginning with "str" invoke
> undefined behavior.
> 
> This is given in the "Future library directions" section.
> 
> "Function names that begin with str, mem, or wcs and a lowercase letter
> may be added to the declarations in the <string.h> header."
> 
> In practice, this doesn't happen just in the future; implementors
> add their own functions, like strdup (POSIX), strcasecmp (various?),
> memchr (GNU) ...
> 
memchr is in the C standard; I guess you meant memrchr, or perhaps the
more obvious (and fun!) memfrob 

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


#156815

FromRichard Damon <Richard@Damon-Family.org>
Date2020-11-29 14:01 -0500
Message-ID<2eSwH.106713$ql4.20950@fx39.iad>
In reply to#156803
On 11/29/20 4:41 AM, Juha Nieminen wrote:
> In comp.lang.c++ Siri Cruise <chine.bleu@yahoo.com> wrote:
>> This is my code
>>
>>     int stringcompare ( /*String comparison for qsort.*/
>>         const ptr a, const ptr b
>>     ) {
>>         char **A = a, **B = b;
>>         return strcmp(*A, *B);
>>     }
> 
> Ah, I love how in C you just implicitly cast from const void* to
> non-const char** without a worry in the world, happily ignoring
> the compiler warnings, because what does the compiler know anyway?
> It's just a dumb program.
> 
> Also love how the comparator function is non-static, throwing it in the
> global namespace. Better not have any other function with that name
> anywhere else. But how likely is that? After all, "stringcompare" is
> such a unique name. The chances that anybody will ever use that same
> name anywhere are astronomically minuscule.
> 

Actually, if ptr is a typedef for void* then a 'const ptr' is a
'void *const' not a 'const void*' if I remember the rules right.

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


#156823

FromJuha Nieminen <nospam@thanks.invalid>
Date2020-11-30 09:05 +0000
Message-ID<rq2ck9$n4i$2@gioia.aioe.org>
In reply to#156815
In comp.lang.c++ Richard Damon <Richard@damon-family.org> wrote:
> On 11/29/20 4:41 AM, Juha Nieminen wrote:
>> In comp.lang.c++ Siri Cruise <chine.bleu@yahoo.com> wrote:
>>> This is my code
>>>
>>>     int stringcompare ( /*String comparison for qsort.*/
>>>         const ptr a, const ptr b
>>>     ) {
>>>         char **A = a, **B = b;
>>>         return strcmp(*A, *B);
>>>     }
>> 
>> Ah, I love how in C you just implicitly cast from const void* to
>> non-const char** without a worry in the world, happily ignoring
>> the compiler warnings, because what does the compiler know anyway?
>> It's just a dumb program.
>> 
>> Also love how the comparator function is non-static, throwing it in the
>> global namespace. Better not have any other function with that name
>> anywhere else. But how likely is that? After all, "stringcompare" is
>> such a unique name. The chances that anybody will ever use that same
>> name anywhere are astronomically minuscule.
> 
> Actually, if ptr is a typedef for void* then a 'const ptr' is a
> 'void *const' not a 'const void*' if I remember the rules right.

Given that qsort takes a parameter of type int(*)(const void*, const void*)
I have to wonder how kosher it is to give it something else. I suppose it
will work with any pointer types, at least if you ignore the warnings...

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


#156825

FromRichard Damon <Richard@Damon-Family.org>
Date2020-11-30 07:09 -0500
Message-ID<Ph5xH.13487$ev6.11497@fx14.iad>
In reply to#156823
On 11/30/20 4:05 AM, Juha Nieminen wrote:
> In comp.lang.c++ Richard Damon <Richard@damon-family.org> wrote:
>> On 11/29/20 4:41 AM, Juha Nieminen wrote:
>>> In comp.lang.c++ Siri Cruise <chine.bleu@yahoo.com> wrote:
>>>> This is my code
>>>>
>>>>     int stringcompare ( /*String comparison for qsort.*/
>>>>         const ptr a, const ptr b
>>>>     ) {
>>>>         char **A = a, **B = b;
>>>>         return strcmp(*A, *B);
>>>>     }
>>>
>>> Ah, I love how in C you just implicitly cast from const void* to
>>> non-const char** without a worry in the world, happily ignoring
>>> the compiler warnings, because what does the compiler know anyway?
>>> It's just a dumb program.
>>>
>>> Also love how the comparator function is non-static, throwing it in the
>>> global namespace. Better not have any other function with that name
>>> anywhere else. But how likely is that? After all, "stringcompare" is
>>> such a unique name. The chances that anybody will ever use that same
>>> name anywhere are astronomically minuscule.
>>
>> Actually, if ptr is a typedef for void* then a 'const ptr' is a
>> 'void *const' not a 'const void*' if I remember the rules right.
> 
> Given that qsort takes a parameter of type int(*)(const void*, const void*)
> I have to wonder how kosher it is to give it something else. I suppose it
> will work with any pointer types, at least if you ignore the warnings...
> 

void * pointers may have a different represntation than most other
pointers (I think it must match char * pointers), this is to allow word
access machines to create special pointing to byte pointers.

You likely can get away with the function having a different type of
pointer than declared, as long as those pointers have the sam
representation, but then you are still running in 'Undefined Behavior'
territory unless the compiler makes special promises.

This means that you really should create your comparing function with
the right prototype, and change the pointer type in the function.

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


#156827

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-11-30 13:06 +0000
Message-ID<87r1obyoxz.fsf@bsb.me.uk>
In reply to#156823
Juha Nieminen <nospam@thanks.invalid> writes:

> Given that qsort takes a parameter of type int(*)(const void*, const void*)
> I have to wonder how kosher it is to give it something else. I suppose it
> will work with any pointer types, at least if you ignore the
> warnings...

I'm not sure what you are saying here.  qsort takes void * data pointers
and it's qsort that constructs the const void * data pointer to pass to
the comparison function.  I'm not sure how you think qsort can "give it
something else".

-- 
Ben.

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


#156828

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-11-30 06:28 -0800
Message-ID<1237ee4d-e74a-469c-83a6-b96ec18af0a7n@googlegroups.com>
In reply to#156827
On Monday, 30 November 2020 at 13:06:17 UTC, Ben Bacarisse wrote:
> Juha Nieminen <nos...@thanks.invalid> writes: 
> 
> > Given that qsort takes a parameter of type int(*)(const void*, const void*) 
> > I have to wonder how kosher it is to give it something else. I suppose it 
> > will work with any pointer types, at least if you ignore the 
> > warnings...
> I'm not sure what you are saying here. qsort takes void * data pointers 
> and it's qsort that constructs the const void * data pointer to pass to 
> the comparison function. I'm not sure how you think qsort can "give it 
> something else". 
> 
He's saying that given the common situation where we want to compare
two struct "employees".
The natural way to write the comparison function is

int comparemployees(const struct employee *empa, const struct employee *empb)
{
    return empb->payroll - empa->payroll;
}

so can we call 

qsort(employees, Nemployees, sizeof(employee), compareemployees);

The answer is not if you want to be strictly portable. You need to write

int compfuncr(const void *a, const void *b)
{
   const struct employee *empa = a;
   const struct employee *empb = b;

   return empb->payroll - empa->payroll;
}

The signature of the function passed to qsort needs to match. 

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


#156833

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-11-30 15:50 +0000
Message-ID<87a6uyzvwh.fsf@bsb.me.uk>
In reply to#156828
Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:

> On Monday, 30 November 2020 at 13:06:17 UTC, Ben Bacarisse wrote:
>> Juha Nieminen <nos...@thanks.invalid> writes: 
>> 
>> > Given that qsort takes a parameter of type int(*)(const void*, const void*) 
>> > I have to wonder how kosher it is to give it something else. I suppose it 
>> > will work with any pointer types, at least if you ignore the 
>> > warnings...
>> I'm not sure what you are saying here. qsort takes void * data pointers 
>> and it's qsort that constructs the const void * data pointer to pass to 
>> the comparison function. I'm not sure how you think qsort can "give it 
>> something else". 
>> 
> He's saying that given the common situation where we want to compare
> two struct "employees".
> The natural way to write the comparison function is
>
> int comparemployees(const struct employee *empa, const struct employee *empb)
> {
>     return empb->payroll - empa->payroll;
> }
>
> so can we call 
>
> qsort(employees, Nemployees, sizeof(employee), compareemployees);

Here's a case that illustrates what I was talking about in another post.
I can't tell by inspection if sizeof(employee) is the right size.  Maybe
it was supposed to be sizeof (struct employee) but even so I would still
have to check the declaration of employees.  sizeof *employees can be
verified roght here.

> The answer is not if you want to be strictly portable.

Yes, I worked on a C compiler for a machine where the above would go
horribly wrong.

> You need to write
>
> int compfuncr(const void *a, const void *b)
> {
>    const struct employee *empa = a;
>    const struct employee *empb = b;
>
>    return empb->payroll - empa->payroll;
> }

If I needed a comparemployees function as well, a neat solution is

  int comp_for_qsort(const void *a, const void *b)
  { return comparemployees(a, b); }

Sometimes I do it that was anyway, just because I prefer function
calling over initialising variables.

-- 
Ben.

[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