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


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

Word For Today: “Uglification”

Started byLawrence D'Oliveiro <ldo@nz.invalid>
First post2024-03-12 00:14 +0000
Last post2024-03-12 06:15 +0000
Articles 20 on this page of 69 — 13 participants

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


Contents

  Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-12 00:14 +0000
    Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-11 18:15 -0700
      Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-12 01:34 +0000
        Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-11 19:56 -0700
    Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-12 03:30 +0000
      Re: Word For Today: “Uglification” Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-03-14 10:23 -0700
        Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-14 14:31 -0700
          Re: Word For Today: “Uglification” scott@slp53.sl.home (Scott Lurndal) - 2024-03-14 23:59 +0000
            Re: Word For Today: “Uglification” scott@slp53.sl.home (Scott Lurndal) - 2024-03-15 00:01 +0000
            Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-14 17:11 -0700
              Re: Word For Today: “Uglification” scott@slp53.sl.home (Scott Lurndal) - 2024-03-15 00:33 +0000
              Re: Word For Today: “Uglification” David Brown <david.brown@hesbynett.no> - 2024-03-15 09:15 +0100
          Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-14 17:15 -0700
            Re: Word For Today: “Uglification” scott@slp53.sl.home (Scott Lurndal) - 2024-03-15 00:34 +0000
              Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-14 19:19 -0700
                Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-15 03:17 +0000
                  Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-14 20:44 -0700
                    Re: Word For Today: “Uglification” David Brown <david.brown@hesbynett.no> - 2024-03-15 09:22 +0100
          Re: Word For Today: “Uglification” Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-03-14 19:49 -0700
    Re: Word For Today: “Uglification” James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-03-12 01:33 -0400
      Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-12 06:14 +0000
        Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-12 06:21 +0000
        Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-12 07:44 +0000
          Re: Word For Today: “Uglification” Richard Kettlewell <invalid@invalid.invalid> - 2024-03-12 08:03 +0000
            Re: Word For Today: “Uglification” David Brown <david.brown@hesbynett.no> - 2024-03-12 11:10 +0100
              Re: Word For Today: “Uglification” Anton Shepelev <anton.txt@g{oogle}mail.com> - 2024-03-12 17:46 +0300
                Re: Word For Today: “Uglification” bart <bc@freeuk.com> - 2024-03-12 14:53 +0000
                  Re: Word For Today: “Uglification” Anton Shepelev <anton.txt@g{oogle}mail.com> - 2024-03-12 18:09 +0300
                    Re: Word For Today: “Uglification” bart <bc@freeuk.com> - 2024-03-12 15:42 +0000
                      Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-12 18:50 +0000
                        Re: Word For Today: “Uglification” bart <bc@freeuk.com> - 2024-03-12 22:29 +0000
                          Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-12 16:00 -0700
                            Re: Word For Today: “Uglification” bart <bc@freeuk.com> - 2024-03-13 11:45 +0000
                              Re: Word For Today: “Uglification” Michael S <already5chosen@yahoo.com> - 2024-03-13 14:12 +0200
                                Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-13 08:15 -0700
                                  Re: Word For Today: “Uglification” David Brown <david.brown@hesbynett.no> - 2024-03-13 18:47 +0100
                                    Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-13 11:56 -0700
                                      Re: Word For Today: “Uglification” David Brown <david.brown@hesbynett.no> - 2024-03-13 22:07 +0100
                                Re: Word For Today: “Uglification” David Brown <david.brown@hesbynett.no> - 2024-03-13 16:40 +0100
                                Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-13 15:48 +0000
                              Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-13 09:03 -0700
                                Re: Word For Today: “Uglification” bart <bc@freeuk.com> - 2024-03-13 16:44 +0000
                            Re: Word For Today: “Uglification” Nick Bowler <nbowler@draconx.ca> - 2024-03-13 17:01 +0000
                          Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-13 02:53 +0000
                  Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-12 18:42 +0000
              Re: Word For Today: “Uglification” Blue-Maned_Hawk <bluemanedhawk@invalid.invalid> - 2024-03-12 22:07 +0000
            Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-12 23:13 +0000
              Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-12 16:29 -0700
                Re: Word For Today: “Uglification” Richard Kettlewell <invalid@invalid.invalid> - 2024-03-13 09:01 +0000
                  Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-13 08:06 -0700
                    Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-13 21:51 +0000
                      Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-13 22:16 +0000
                      Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-13 15:26 -0700
                      Re: Word For Today: “Uglification” scott@slp53.sl.home (Scott Lurndal) - 2024-03-13 22:33 +0000
                        Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-13 22:50 +0000
                          Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-13 16:06 -0700
                            Re: Word For Today: “Uglification” Richard Kettlewell <invalid@invalid.invalid> - 2024-03-13 23:32 +0000
                            Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-14 00:40 +0000
                          Re: Word For Today: “Uglification” scott@slp53.sl.home (Scott Lurndal) - 2024-03-13 23:15 +0000
                    Re: Word For Today: “Uglification” Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-06-18 23:09 -0700
              Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-13 00:23 +0000
        Re: Word For Today: “Uglification” James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-03-12 11:51 -0400
          Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-12 21:31 +0000
            Re: Word For Today: “Uglification” Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-03-12 15:21 -0700
            Re: Word For Today: “Uglification” James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-03-13 03:36 -0400
              Re: Word For Today: “Uglification” Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-03-13 21:52 +0000
                Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-13 22:10 +0000
                Re: Word For Today: “Uglification” James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-03-13 20:47 -0400
    Re: Word For Today: “Uglification” Kaz Kylheku <433-929-6894@kylheku.com> - 2024-03-12 06:15 +0000

Page 1 of 4  [1] 2 3 4  Next page →


#383532 — Word For Today: “Uglification”

FromLawrence D'Oliveiro <ldo@nz.invalid>
Date2024-03-12 00:14 +0000
SubjectWord For Today: “Uglification”
Message-ID<uso6or$3t3jn$3@dont-email.me>
From /usr/include/«arch»/bits/select.h on my Debian system:

    #define __FD_ZERO(s) \
      do {									      \
        unsigned int __i;							      \
        fd_set *__arr = (s);						      \
        for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)	      \
          __FDS_BITS (__arr)[__i] = 0;					      \
      } while (0)

Note how this macro brings the entire expression for “s” into the
scope containing those temporary “__i” and “__arr” variables. You just
better hope they won’t clash.

I think there is a clause in the C spec that says names beginning with
underscores (“uglified” names, I think they’re called) are reserved
for library implementors or something. But what happens if one library
implementation depends on another? What keeps the choices of names
from clashing in that situation? Just luck, I guess.

Basically, string-substitution macros are fiddly, fragile, and prone
to mysterious syntax errors in the target language if you’re not
careful. I thought initially that this was down to limitations in the
the C/C++ preprocessor; maybe a more powerful one, like m4, would
help. But it turns that is even more fiddly and fragile, and prone to
mysterious syntax errors if you’re not careful.

[toc] | [next] | [standalone]


#383534

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-03-11 18:15 -0700
Message-ID<87wmq88d45.fsf@nosuchdomain.example.com>
In reply to#383532
Lawrence D'Oliveiro <ldo@nz.invalid> writes:
> From /usr/include/«arch»/bits/select.h on my Debian system:
>
>     #define __FD_ZERO(s) \
>       do {									      \
>         unsigned int __i;							      \
>         fd_set *__arr = (s);						      \
>         for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)	      \
>           __FDS_BITS (__arr)[__i] = 0;					      \
>       } while (0)
>
> Note how this macro brings the entire expression for “s” into the
> scope containing those temporary “__i” and “__arr” variables. You just
> better hope they won’t clash.
>
> I think there is a clause in the C spec that says names beginning with
> underscores (“uglified” names, I think they’re called) are reserved
> for library implementors or something. But what happens if one library
> implementation depends on another? What keeps the choices of names
> from clashing in that situation? Just luck, I guess.

N1570 7.1.3:

    All identifiers that begin with an underscore and either an
    uppercase letter or another underscore are always reserved for any
    use.

    All identifiers that begin with an underscore are always reserved
    for use as identifiers with file scope in both the ordinary and tag
    name spaces.

I've never heard them call "uglified", though I suppose it's somewhat apt.

If the standard library includes code from two or more different
implementers, all implementers have a very strong interest in avoiding
any clashes.  I don't see a real problem here.

[...]

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

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


#383536

FromLawrence D'Oliveiro <ldo@nz.invalid>
Date2024-03-12 01:34 +0000
Message-ID<usober$3u4ig$1@dont-email.me>
In reply to#383534
On Mon, 11 Mar 2024 18:15:06 -0700, Keith Thompson wrote:

> If the standard library includes code from two or more different
> implementers, all implementers have a very strong interest in avoiding
> any clashes.  I don't see a real problem here.

... until the Birthday Paradox comes into play.

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


#383537

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-03-11 19:56 -0700
Message-ID<87o7bk88ew.fsf@nosuchdomain.example.com>
In reply to#383536
Lawrence D'Oliveiro <ldo@nz.invalid> writes:
> On Mon, 11 Mar 2024 18:15:06 -0700, Keith Thompson wrote:
>
>> If the standard library includes code from two or more different
>> implementers, all implementers have a very strong interest in avoiding
>> any clashes.  I don't see a real problem here.
>
> ... until the Birthday Paradox comes into play.

The Birthday Paradox comes into play for random birthdays over which the
participants have no control, not for library implementers who control
their own namespaces and are strongly motivated to avoid collisions.

Do you have a real-world example of such a collision?

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

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


#383539

FromKaz Kylheku <433-929-6894@kylheku.com>
Date2024-03-12 03:30 +0000
Message-ID<20240311202758.193@kylheku.com>
In reply to#383532
On 2024-03-12, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
> From /usr/include/«arch»/bits/select.h on my Debian system:
>
>     #define __FD_ZERO(s) \
>       do {									      \
>         unsigned int __i;							      \
>         fd_set *__arr = (s);						      \

This assignment has value; it checks that, loosely speaking,
s is an "assignment compatible" pointer with a fd_set *,
so that there is a diagnostic if the macro is applied to
an object of the wrong type.

>         for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)	      \
>           __FDS_BITS (__arr)[__i] = 0;					      \

Here, I would have done memset(__arr, 0, sizeof *__arr).

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

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


#383607

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2024-03-14 10:23 -0700
Message-ID<86v85opw22.fsf@linuxsc.com>
In reply to#383539
Kaz Kylheku <433-929-6894@kylheku.com> writes:

[some editing of white space done]

> On 2024-03-12, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
>
>> From /usr/include/<<arch>>/bits/select.h on my Debian system:
>>
>>   #define __FD_ZERO(s)                                                  \
>>     do {                                                                \
>>       unsigned int __i;                                                 \
>>       fd_set *__arr = (s);                                              \
>
> This assignment has value;  it checks that, loosely speaking,
> s is an "assignment compatible" pointer with a fd_set *,
> so that there is a diagnostic if the macro is applied to
> an object of the wrong type.

More to the point, if the macro is applied to a value of the wrong
type.

>>       for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)  \
>>         __FDS_BITS (__arr)[__i] = 0;                                    \
>
> Here, I would have done memset(__arr, 0, sizeof *__arr).

That assumes that it is the entire fd_set that needs to be zeroed,
which may not be right.  Note the call to the __FDS_BITS() macro.

Better:

  #define __FD_ZERO(s) (                                                  \
    (void) memset(                                                        \
      __FDS_BITS( (fd_set*){(s)} ), 0, sizeof __FDS_BITS( (fd_set*){0} )  \
    )                                                                     \
  )

This definition:  avoids introducing any new identifiers;  checks
that the argument s yields an assignment compatible pointer;  and
provides a macro that can be used as a void expression (unlike the
original macro definition, which can be used only as a statement).

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


#383611

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-03-14 14:31 -0700
Message-ID<87v85o4i1v.fsf@nosuchdomain.example.com>
In reply to#383607
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Kaz Kylheku <433-929-6894@kylheku.com> writes:
>
> [some editing of white space done]
>
>> On 2024-03-12, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
>>
>>> From /usr/include/<<arch>>/bits/select.h on my Debian system:
>>>
>>>   #define __FD_ZERO(s)                                                  \
>>>     do {                                                                \
>>>       unsigned int __i;                                                 \
>>>       fd_set *__arr = (s);                                              \
>>
>> This assignment has value;  it checks that, loosely speaking,
>> s is an "assignment compatible" pointer with a fd_set *,
>> so that there is a diagnostic if the macro is applied to
>> an object of the wrong type.
>
> More to the point, if the macro is applied to a value of the wrong
> type.
>
>>>       for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)  \
>>>         __FDS_BITS (__arr)[__i] = 0;                                    \
>>
>> Here, I would have done memset(__arr, 0, sizeof *__arr).
>
> That assumes that it is the entire fd_set that needs to be zeroed,
> which may not be right.  Note the call to the __FDS_BITS() macro.
>
> Better:
>
>   #define __FD_ZERO(s) (                                                  \
>     (void) memset(                                                        \
>       __FDS_BITS( (fd_set*){(s)} ), 0, sizeof __FDS_BITS( (fd_set*){0} )  \
>     )                                                                     \
>   )
>
> This definition:  avoids introducing any new identifiers;  checks
> that the argument s yields an assignment compatible pointer;  and
> provides a macro that can be used as a void expression (unlike the
> original macro definition, which can be used only as a statement).

For context, here's the entire file from my system (Ubuntu 24.0.4,
package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
author(s) decided not to use memset to avoid the required #include,
which might increase compilation times for code that indirectly includes
this header.  (I offer no opinion on whether that's a good tradeoff.)

Note that __FD_ZERO is very clearly *not* intended to be invoked by
arbitrary code.

```
/* Copyright (C) 1997-2022 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <https://www.gnu.org/licenses/>.  */

#ifndef _SYS_SELECT_H
# error "Never use <bits/select.h> directly; include <sys/select.h> instead."
#endif


/* We don't use `memset' because this would require a prototype and
   the array isn't too big.  */
#define __FD_ZERO(s) \
  do {									      \
    unsigned int __i;							      \
    fd_set *__arr = (s);						      \
    for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)	      \
      __FDS_BITS (__arr)[__i] = 0;					      \
  } while (0)
#define __FD_SET(d, s) \
  ((void) (__FDS_BITS (s)[__FD_ELT(d)] |= __FD_MASK(d)))
#define __FD_CLR(d, s) \
  ((void) (__FDS_BITS (s)[__FD_ELT(d)] &= ~__FD_MASK(d)))
#define __FD_ISSET(d, s) \
  ((__FDS_BITS (s)[__FD_ELT (d)] & __FD_MASK (d)) != 0)

```

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

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


#383618

Fromscott@slp53.sl.home (Scott Lurndal)
Date2024-03-14 23:59 +0000
Message-ID<bbMIN.411923$vFZa.142318@fx13.iad>
In reply to#383611
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>> Kaz Kylheku <433-929-6894@kylheku.com> writes:
>>
>> [some editing of white space done]
>>
>>> On 2024-03-12, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
>>>
>>>> From /usr/include/<<arch>>/bits/select.h on my Debian system:
>>>>
>>>>   #define __FD_ZERO(s)                                                  \
>>>>     do {                                                                \
>>>>       unsigned int __i;                                                 \
>>>>       fd_set *__arr = (s);                                              \
>>>
>>> This assignment has value;  it checks that, loosely speaking,
>>> s is an "assignment compatible" pointer with a fd_set *,
>>> so that there is a diagnostic if the macro is applied to
>>> an object of the wrong type.
>>
>> More to the point, if the macro is applied to a value of the wrong
>> type.
>>
>>>>       for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)  \
>>>>         __FDS_BITS (__arr)[__i] = 0;                                    \
>>>
>>> Here, I would have done memset(__arr, 0, sizeof *__arr).
>>
>> That assumes that it is the entire fd_set that needs to be zeroed,
>> which may not be right.  Note the call to the __FDS_BITS() macro.
>>
>> Better:
>>
>>   #define __FD_ZERO(s) (                                                  \
>>     (void) memset(                                                        \
>>       __FDS_BITS( (fd_set*){(s)} ), 0, sizeof __FDS_BITS( (fd_set*){0} )  \
>>     )                                                                     \
>>   )
>>
>> This definition:  avoids introducing any new identifiers;  checks
>> that the argument s yields an assignment compatible pointer;  and
>> provides a macro that can be used as a void expression (unlike the
>> original macro definition, which can be used only as a statement).
>
>For context, here's the entire file from my system (Ubuntu 24.0.4,
>package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>author(s) decided not to use memset to avoid the required #include,
>which might increase compilation times for code that indirectly includes
>this header.  (I offer no opinion on whether that's a good tradeoff.)
>
>Note that __FD_ZERO is very clearly *not* intended to be invoked by
>arbitrary code.
>
>```
>/* Copyright (C) 1997-2022 Free Software Foundation, Inc.
>   This file is part of the GNU C Library.
>
>   The GNU C Library is free software; you can redistribute it and/or
>   modify it under the terms of the GNU Lesser General Public
>   License as published by the Free Software Foundation; either
>   version 2.1 of the License, or (at your option) any later version.
>
>   The GNU C Library is distributed in the hope that it will be useful,
>   but WITHOUT ANY WARRANTY; without even the implied warranty of
>   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>   Lesser General Public License for more details.
>
>   You should have received a copy of the GNU Lesser General Public
>   License along with the GNU C Library; if not, see
>   <https://www.gnu.org/licenses/>.  */
>
>#ifndef _SYS_SELECT_H
># error "Never use <bits/select.h> directly; include <sys/select.h> instead."
>#endif
>
>
>/* We don't use `memset' because this would require a prototype and
>   the array isn't too big.  */
>#define __FD_ZERO(s) \
>  do {									      \
>    unsigned int __i;							      \
>    fd_set *__arr = (s);						      \
>    for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)	      \
>      __FDS_BITS (__arr)[__i] = 0;					      \
>  } while (0)
>#define __FD_SET(d, s) \
>  ((void) (__FDS_BITS (s)[__FD_ELT(d)] |= __FD_MASK(d)))
>#define __FD_CLR(d, s) \
>  ((void) (__FDS_BITS (s)[__FD_ELT(d)] &= ~__FD_MASK(d)))
>#define __FD_ISSET(d, s) \
>  ((__FDS_BITS (s)[__FD_ELT (d)] & __FD_MASK (d)) != 0)
>
>```
>

That code is only selected if it is not compiled with
gcc.  If it is gcc 2 or later, the header file uses

# define __FD_ZERO(fdsp) \
  do {                                                                        \
    int __d0, __d1;                                                           \
    __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS                         \
                          : "=c" (__d0), "=D" (__d1)                          \
                          : "a" (0), "0" (sizeof (fd_set)                     \
                                          / sizeof (__fd_mask)),              \
                            "1" (&__FDS_BITS (fdsp)[0])                       \
                          : "memory");                                        \
  } while (0)

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


#383619

Fromscott@slp53.sl.home (Scott Lurndal)
Date2024-03-15 00:01 +0000
Message-ID<LdMIN.411924$vFZa.113768@fx13.iad>
In reply to#383618
scott@slp53.sl.home (Scott Lurndal) writes:
>Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>> Kaz Kylheku <433-929-6894@kylheku.com> writes:
>>>
>>> [some editing of white space done]
>>>
>>>> On 2024-03-12, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
>>>>
>>>>> From /usr/include/<<arch>>/bits/select.h on my Debian system:
>>>>>
>>>>>   #define __FD_ZERO(s)                                                  \
>>>>>     do {                                                                \
>>>>>       unsigned int __i;                                                 \
>>>>>       fd_set *__arr = (s);                                              \
>>>>
>>>> This assignment has value;  it checks that, loosely speaking,
>>>> s is an "assignment compatible" pointer with a fd_set *,
>>>> so that there is a diagnostic if the macro is applied to
>>>> an object of the wrong type.
>>>
>>> More to the point, if the macro is applied to a value of the wrong
>>> type.
>>>
>>>>>       for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)  \
>>>>>         __FDS_BITS (__arr)[__i] = 0;                                    \
>>>>
>>>> Here, I would have done memset(__arr, 0, sizeof *__arr).
>>>
>>> That assumes that it is the entire fd_set that needs to be zeroed,
>>> which may not be right.  Note the call to the __FDS_BITS() macro.
>>>
>>> Better:
>>>
>>>   #define __FD_ZERO(s) (                                                  \
>>>     (void) memset(                                                        \
>>>       __FDS_BITS( (fd_set*){(s)} ), 0, sizeof __FDS_BITS( (fd_set*){0} )  \
>>>     )                                                                     \
>>>   )
>>>
>>> This definition:  avoids introducing any new identifiers;  checks
>>> that the argument s yields an assignment compatible pointer;  and
>>> provides a macro that can be used as a void expression (unlike the
>>> original macro definition, which can be used only as a statement).
>>
>>For context, here's the entire file from my system (Ubuntu 24.0.4,
>>package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>>author(s) decided not to use memset to avoid the required #include,
>>which might increase compilation times for code that indirectly includes
>>this header.  (I offer no opinion on whether that's a good tradeoff.)
>>
>>Note that __FD_ZERO is very clearly *not* intended to be invoked by
>>arbitrary code.
>>
>>```
>>/* Copyright (C) 1997-2022 Free Software Foundation, Inc.
>>   This file is part of the GNU C Library.
>>
>>   The GNU C Library is free software; you can redistribute it and/or
>>   modify it under the terms of the GNU Lesser General Public
>>   License as published by the Free Software Foundation; either
>>   version 2.1 of the License, or (at your option) any later version.
>>
>>   The GNU C Library is distributed in the hope that it will be useful,
>>   but WITHOUT ANY WARRANTY; without even the implied warranty of
>>   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>   Lesser General Public License for more details.
>>
>>   You should have received a copy of the GNU Lesser General Public
>>   License along with the GNU C Library; if not, see
>>   <https://www.gnu.org/licenses/>.  */
>>
>>#ifndef _SYS_SELECT_H
>># error "Never use <bits/select.h> directly; include <sys/select.h> instead."
>>#endif
>>
>>
>>/* We don't use `memset' because this would require a prototype and
>>   the array isn't too big.  */
>>#define __FD_ZERO(s) \
>>  do {									      \
>>    unsigned int __i;							      \
>>    fd_set *__arr = (s);						      \
>>    for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)	      \
>>      __FDS_BITS (__arr)[__i] = 0;					      \
>>  } while (0)
>>#define __FD_SET(d, s) \
>>  ((void) (__FDS_BITS (s)[__FD_ELT(d)] |= __FD_MASK(d)))
>>#define __FD_CLR(d, s) \
>>  ((void) (__FDS_BITS (s)[__FD_ELT(d)] &= ~__FD_MASK(d)))
>>#define __FD_ISSET(d, s) \
>>  ((__FDS_BITS (s)[__FD_ELT (d)] & __FD_MASK (d)) != 0)
>>
>>```
>>
>
>That code is only selected if it is not compiled with
>gcc.  If it is gcc 2 or later, the header file uses
>
># define __FD_ZERO(fdsp) \
>  do {                                                                        \
>    int __d0, __d1;                                                           \
>    __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS                         \
>                          : "=c" (__d0), "=D" (__d1)                          \
>                          : "a" (0), "0" (sizeof (fd_set)                     \
>                                          / sizeof (__fd_mask)),              \
>                            "1" (&__FDS_BITS (fdsp)[0])                       \
>                          : "memory");                                        \
>  } while (0)
>

 (Fedora Core 20).

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


#383620

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-03-14 17:11 -0700
Message-ID<87r0gc4am0.fsf@nosuchdomain.example.com>
In reply to#383618
scott@slp53.sl.home (Scott Lurndal) writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>For context, here's the entire file from my system (Ubuntu 24.0.4,
>>package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>>author(s) decided not to use memset to avoid the required #include,
>>which might increase compilation times for code that indirectly includes
>>this header.  (I offer no opinion on whether that's a good tradeoff.)
>>
>>Note that __FD_ZERO is very clearly *not* intended to be invoked by
>>arbitrary code.
>>
>>```
[code snipped]
>>```
>>
>
> That code is only selected if it is not compiled with
> gcc.  If it is gcc 2 or later, the header file uses
>
> # define __FD_ZERO(fdsp) \
>   do {                                                                        \
>     int __d0, __d1;                                                           \
>     __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS                         \
>                           : "=c" (__d0), "=D" (__d1)                          \
>                           : "a" (0), "0" (sizeof (fd_set)                     \
>                                           / sizeof (__fd_mask)),              \
>                             "1" (&__FDS_BITS (fdsp)[0])                       \
>                           : "memory");                                        \
>   } while (0)

Oh?  I don't see that code anywhere in the current glibc sources, in any
older version of bits/select.h, or anywhere under /usr/include on my
system.

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

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


#383622

Fromscott@slp53.sl.home (Scott Lurndal)
Date2024-03-15 00:33 +0000
Message-ID<0HMIN.574791$xHn7.519575@fx14.iad>
In reply to#383620
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>scott@slp53.sl.home (Scott Lurndal) writes:
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>For context, here's the entire file from my system (Ubuntu 24.0.4,
>>>package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>>>author(s) decided not to use memset to avoid the required #include,
>>>which might increase compilation times for code that indirectly includes
>>>this header.  (I offer no opinion on whether that's a good tradeoff.)
>>>
>>>Note that __FD_ZERO is very clearly *not* intended to be invoked by
>>>arbitrary code.
>>>
>>>```
>[code snipped]
>>>```
>>>
>>
>> That code is only selected if it is not compiled with
>> gcc.  If it is gcc 2 or later, the header file uses
>>
>> # define __FD_ZERO(fdsp) \
>>   do {                                                                        \
>>     int __d0, __d1;                                                           \
>>     __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS                         \
>>                           : "=c" (__d0), "=D" (__d1)                          \
>>                           : "a" (0), "0" (sizeof (fd_set)                     \
>>                                           / sizeof (__fd_mask)),              \
>>                             "1" (&__FDS_BITS (fdsp)[0])                       \
>>                           : "memory");                                        \
>>   } while (0)
>
>Oh?  I don't see that code anywhere in the current glibc sources, in any
>older version of bits/select.h, or anywhere under /usr/include on my
>system.

I'm using Fedora Core 20.  Should have noted that directly in the reply,
sorry about that.  It had surprised me when I looked at the generated
code, thinking that perhaps the optimizer generated the rep stos
when optimizing the loop.

$ rpm -q -f /usr/include/bits/select.h 
glibc-headers-2.18-19.fc20.x86_64
$ gcc --version
gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)

Yes, I should probably update to a newer Fedora release, but this
has been rock solid for almost a decade (until last week when
an automatic firefox update started requiring wayland libraries).

We do use gcc11+ and recent Ubuntu/Fedora/Redhat release at the office.

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


#383632

FromDavid Brown <david.brown@hesbynett.no>
Date2024-03-15 09:15 +0100
Message-ID<ut103p$2695n$1@dont-email.me>
In reply to#383620
On 15/03/2024 01:11, Keith Thompson wrote:
> scott@slp53.sl.home (Scott Lurndal) writes:
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>> For context, here's the entire file from my system (Ubuntu 24.0.4,
>>> package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>>> author(s) decided not to use memset to avoid the required #include,
>>> which might increase compilation times for code that indirectly includes
>>> this header.  (I offer no opinion on whether that's a good tradeoff.)
>>>
>>> Note that __FD_ZERO is very clearly *not* intended to be invoked by
>>> arbitrary code.
>>>
>>> ```
> [code snipped]
>>> ```
>>>
>>
>> That code is only selected if it is not compiled with
>> gcc.  If it is gcc 2 or later, the header file uses
>>
>> # define __FD_ZERO(fdsp) \
>>    do {                                                                        \
>>      int __d0, __d1;                                                           \
>>      __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS                         \
>>                            : "=c" (__d0), "=D" (__d1)                          \
>>                            : "a" (0), "0" (sizeof (fd_set)                     \
>>                                            / sizeof (__fd_mask)),              \
>>                              "1" (&__FDS_BITS (fdsp)[0])                       \
>>                            : "memory");                                        \
>>    } while (0)
> 
> Oh?  I don't see that code anywhere in the current glibc sources, in any
> older version of bits/select.h, or anywhere under /usr/include on my
> system.
> 

I see it in my older Mint system (based on Ubuntu bionic 18.04 LTS), but 
not my newer one (based on Ubuntu jammy 22.04 LTS).  So it looks like 
was an optimisation that was useful in the past, but newer gcc gives the 
same or better code from the pure C code.  Keeping it in C rather than 
inline assembly gives the compiler more information, even if the 
generated object code is still the same, so that's always a good thing.

(And full memory clobbers are undesirable in performance code because it 
can mean the compiler loses useful knowledge or has to re-load other 
data from memory.)

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


#383621

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-03-14 17:15 -0700
Message-ID<87msr04afd.fsf@nosuchdomain.example.com>
In reply to#383611
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
[...]
> For context, here's the entire file from my system (Ubuntu 24.0.4,
> package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
> author(s) decided not to use memset to avoid the required #include,
> which might increase compilation times for code that indirectly includes
> this header.  (I offer no opinion on whether that's a good tradeoff.)
[...]

An older version did use memset().  It was changed to use a loop in
1997, with a commit message that included:
    "Don't use memset to prevent prototype trouble, use simple loop."
It may have been to avoid problems with pre-ANSI C compilers that didn't
support prototypes.  That's still speculation on my part.

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

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


#383623

Fromscott@slp53.sl.home (Scott Lurndal)
Date2024-03-15 00:34 +0000
Message-ID<lIMIN.574792$xHn7.491768@fx14.iad>
In reply to#383621
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>[...]
>> For context, here's the entire file from my system (Ubuntu 24.0.4,
>> package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>> author(s) decided not to use memset to avoid the required #include,
>> which might increase compilation times for code that indirectly includes
>> this header.  (I offer no opinion on whether that's a good tradeoff.)
>[...]
>
>An older version did use memset().  It was changed to use a loop in
>1997, with a commit message that included:
>    "Don't use memset to prevent prototype trouble, use simple loop."
>It may have been to avoid problems with pre-ANSI C compilers that didn't
>support prototypes.  That's still speculation on my part.

Here's the full fc20 version:
$ rpm -q -f /usr/include/bits/select.h
glibc-headers-2.18-19.fc20.x86_64


/* Copyright (C) 1997-2013 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#ifndef _SYS_SELECT_H
# error "Never use <bits/select.h> directly; include <sys/select.h> instead."
#endif

#include <bits/wordsize.h>


#if defined __GNUC__ && __GNUC__ >= 2

# if __WORDSIZE == 64
#  define __FD_ZERO_STOS "stosq"
# else
#  define __FD_ZERO_STOS "stosl"
# endif

# define __FD_ZERO(fdsp) \
  do {                                                                        \
    int __d0, __d1;                                                           \
    __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS                         \
                          : "=c" (__d0), "=D" (__d1)                          \
                          : "a" (0), "0" (sizeof (fd_set)                     \
                                          / sizeof (__fd_mask)),              \
                            "1" (&__FDS_BITS (fdsp)[0])                       \
                          : "memory");                                        \
  } while (0)

#else   /* ! GNU CC */

/* We don't use `memset' because this would require a prototype and
   the array isn't too big.  */
# define __FD_ZERO(set)  \
  do {                                                                        \
    unsigned int __i;                                                         \
    fd_set *__arr = (set);                                                    \
    for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)          \
      __FDS_BITS (__arr)[__i] = 0;                                            \
  } while (0)

#endif  /* GNU CC */

#define __FD_SET(d, set) \
  ((void) (__FDS_BITS (set)[__FD_ELT (d)] |= __FD_MASK (d)))
#define __FD_CLR(d, set) \
  ((void) (__FDS_BITS (set)[__FD_ELT (d)] &= ~__FD_MASK (d)))
#define __FD_ISSET(d, set) \
  ((__FDS_BITS (set)[__FD_ELT (d)] & __FD_MASK (d)) != 0)

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


#383624

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-03-14 19:19 -0700
Message-ID<87il1o44oi.fsf@nosuchdomain.example.com>
In reply to#383623
scott@slp53.sl.home (Scott Lurndal) writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>[...]
>>> For context, here's the entire file from my system (Ubuntu 24.0.4,
>>> package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>>> author(s) decided not to use memset to avoid the required #include,
>>> which might increase compilation times for code that indirectly includes
>>> this header.  (I offer no opinion on whether that's a good tradeoff.)
>>[...]
>>
>>An older version did use memset().  It was changed to use a loop in
>>1997, with a commit message that included:
>>    "Don't use memset to prevent prototype trouble, use simple loop."
>>It may have been to avoid problems with pre-ANSI C compilers that didn't
>>support prototypes.  That's still speculation on my part.
>
> Here's the full fc20 version:
> $ rpm -q -f /usr/include/bits/select.h
> glibc-headers-2.18-19.fc20.x86_64
>
>
[...]
> #if defined __GNUC__ && __GNUC__ >= 2
[...]
> #else   /* ! GNU CC */
[...]
> #endif  /* GNU CC */
[...]

I don't see that in the GNU glibc git repo, even on branches with
"fedora" in their names.  Perhaps it's a change applied by Red Hat and
not propagated upstream.  (Though I'm not sure why Red Hat would need to
allow for glibc not being compiled by gcc.)

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

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


#383627

FromKaz Kylheku <433-929-6894@kylheku.com>
Date2024-03-15 03:17 +0000
Message-ID<20240314195148.755@kylheku.com>
In reply to#383624
On 2024-03-15, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
> scott@slp53.sl.home (Scott Lurndal) writes:
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>[...]
>>>> For context, here's the entire file from my system (Ubuntu 24.0.4,
>>>> package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
>>>> author(s) decided not to use memset to avoid the required #include,
>>>> which might increase compilation times for code that indirectly includes
>>>> this header.  (I offer no opinion on whether that's a good tradeoff.)
>>>[...]
>>>
>>>An older version did use memset().  It was changed to use a loop in
>>>1997, with a commit message that included:
>>>    "Don't use memset to prevent prototype trouble, use simple loop."
>>>It may have been to avoid problems with pre-ANSI C compilers that didn't
>>>support prototypes.  That's still speculation on my part.
>>
>> Here's the full fc20 version:
>> $ rpm -q -f /usr/include/bits/select.h
>> glibc-headers-2.18-19.fc20.x86_64
>>
>>
> [...]
>> #if defined __GNUC__ && __GNUC__ >= 2

Whoever wrote this didn't know that if __GNUC__ doesn't exist, it will
expand as 0, which is false, so this is equivalent to just

  #if __GNUC__ >= 2

> [...]
>> #else   /* ! GNU CC */
> [...]
>> #endif  /* GNU CC */
> [...]
>
> I don't see that in the GNU glibc git repo, even on branches with
> "fedora" in their names.  Perhaps it's a change applied by Red Hat and
> not propagated upstream.  (Though I'm not sure why Red Hat would need to
> allow for glibc not being compiled by gcc.)

That it's checking for GNU C at least 2 suggests it is an old
patch.

If you look at the source directory for Fedora's package, you see
there are a bunch of patches that get applied:

https://src.fedoraproject.org/rpms/glibc/tree/rawhide

Now if we go to "f20", a heck of lot more patches were applied:

https://src.fedoraproject.org/rpms/glibc/tree/f20

Now, don't waste your time; it's not in any of those patches (I looked).

f20 references glibc-2.18.tar.gz, and that's where that code is found,
in this file:

  ./glibc-2.18/sysdeps/x86/bits/select.h

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

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


#383628

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-03-14 20:44 -0700
Message-ID<878r2k40qv.fsf@nosuchdomain.example.com>
In reply to#383627
Kaz Kylheku <433-929-6894@kylheku.com> writes:
[...]
>>> #if defined __GNUC__ && __GNUC__ >= 2
>
> Whoever wrote this didn't know that if __GNUC__ doesn't exist, it will
> expand as 0, which is false, so this is equivalent to just
>
>   #if __GNUC__ >= 2

Or they did know that and decided that the longer version would be clearer.

[...]

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

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


#383633

FromDavid Brown <david.brown@hesbynett.no>
Date2024-03-15 09:22 +0100
Message-ID<ut10gu$2695n$2@dont-email.me>
In reply to#383628
On 15/03/2024 04:44, Keith Thompson wrote:
> Kaz Kylheku <433-929-6894@kylheku.com> writes:
> [...]
>>>> #if defined __GNUC__ && __GNUC__ >= 2
>>
>> Whoever wrote this didn't know that if __GNUC__ doesn't exist, it will
>> expand as 0, which is false, so this is equivalent to just
>>
>>    #if __GNUC__ >= 2
> 
> Or they did know that and decided that the longer version would be clearer.
> 

Or they did know, and decided they did not want a spurious warning when 
compiling with "-Wundef" that generates a warning before replacing 
undefined identifiers with 0 in #if directives.  Personally, I always 
use -Wundef in my own code, because I think the "default to 0" treatment 
makes it far too easy for typos to go unnoticed.  I have no idea if the 
glibc folk agree with that and like to use -Wundef themselves, or if 
they just like to make their code as "warning-proof" as possible.

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


#383625

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2024-03-14 19:49 -0700
Message-ID<86il1op5uk.fsf@linuxsc.com>
In reply to#383611
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Kaz Kylheku <433-929-6894@kylheku.com> writes:
>>
>> [some editing of white space done]
>>
>>> On 2024-03-12, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
>>>
>>>> From /usr/include/<<arch>>/bits/select.h on my Debian system:
>>>>
>>>>   #define __FD_ZERO(s)                                                  \
>>>>     do {                                                                \
>>>>       unsigned int __i;                                                 \
>>>>       fd_set *__arr = (s);                                              \
>>>
>>> This assignment has value;  it checks that, loosely speaking,
>>> s is an "assignment compatible" pointer with a fd_set *,
>>> so that there is a diagnostic if the macro is applied to
>>> an object of the wrong type.
>>
>> More to the point, if the macro is applied to a value of the wrong
>> type.
>>
>>>>       for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)  \
>>>>         __FDS_BITS (__arr)[__i] = 0;                                    \
>>>
>>> Here, I would have done memset(__arr, 0, sizeof *__arr).
>>
>> That assumes that it is the entire fd_set that needs to be zeroed,
>> which may not be right.  Note the call to the __FDS_BITS() macro.
>>
>> Better:
>>
>>   #define __FD_ZERO(s) (                                                  \
>>     (void) memset(                                                        \
>>       __FDS_BITS( (fd_set*){(s)} ), 0, sizeof __FDS_BITS( (fd_set*){0} )  \
>>     )                                                                     \
>>   )
>>
>> This definition:  avoids introducing any new identifiers;  checks
>> that the argument s yields an assignment compatible pointer;  and
>> provides a macro that can be used as a void expression (unlike the
>> original macro definition, which can be used only as a statement).
>
> For context, here's the entire file from my system (Ubuntu 24.0.4,
> package libc6-dev:amd64 2.35-0ubuntu3.6).  I get the impression that the
> author(s) decided not to use memset to avoid the required #include,
> which might increase compilation times for code that indirectly includes
> this header.  [...]

Yes, it seems clear from the (snipped) source that the authors
deliberately avoided using memset(), perhaps so as not to have
an unwanted dependency.

My comments were meant in the sense of comparing one revision to
another, and about macro definitions generally.  They were not
meant to say anything specific about the context in which the
original macro was defined, both because it is not one I have
easy access to and because it doesn't affect the general nature
of my comments.

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


#383540

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2024-03-12 01:33 -0400
Message-ID<usopec$4eob$1@dont-email.me>
In reply to#383532
On 3/11/24 20:14, Lawrence D'Oliveiro wrote:
> From /usr/include/«arch»/bits/select.h on my Debian system:
> 
>     #define __FD_ZERO(s) \
>       do {									      \
>         unsigned int __i;							      \
>         fd_set *__arr = (s);						      \
>         for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i)	      \
>           __FDS_BITS (__arr)[__i] = 0;					      \
>       } while (0)
> 
> Note how this macro brings the entire expression for “s” into the
> scope containing those temporary “__i” and “__arr” variables. You just
> better hope they won’t clash.
> 
> I think there is a clause in the C spec that says names beginning with
> underscores (“uglified” names, I think they’re called) are reserved
> for library implementors or something. But what happens if one library
> implementation depends on another? What keeps the choices of names
> from clashing in that situation? Just luck, I guess.

They are called "reserved identifiers", a name which more directly
addresses their purpose. They don't just start with underscores - there
are several different sets of identifiers, reserved for different
purposes. See section 7.1.3 for details. They are provided by *an*
implementation. Note the use of the singular. As far as the standard is
concerned, there is only one implementation that is responsible for
translating and executing a given program. What the implementation
implements is not just the C standard library, but also the C language.
Libraries other than the C standard library do have implementations, but
those implementations are not what the C standard is usually talking
about when it uses that word.

The standard defines an implementation as "particular set of software,
running in a particular translation environment under particular control
options, that performs translation of programs for, and supports
execution of functions in, a particular execution environment" (3.12).

Note that the software must be running before it can be called an
implementation. A program that is just sitting on your computer waiting
to be executed cannot qualify. Also, if the software has options,
choosing different options when you start it up can make it a different
implementation of C.

You can have an implementation of C where different parts are
implemented by different implementors - in fact, it's quite common for
the language, the C standard library, and the linker to be implemented
by different organizations. However, the combination of those parts only
qualifies as a conforming implementation of C if those different parts
work together as required by the standard. Avoiding the conflicts you're
talking about is a pre-requisite for doing so.

Most implementors that implement only part of a C implementation make
sure to test whether their part works together with popular
implementations of the other parts, and to document which ones they do
work with. If you cobble together a complete implementation from parts
implemented by different implementors, you'd better check their
documentation to see if at least one of them has tested compatibility
with all of the others. If none of them has done such testing, you
shouldn't count on them working together as a conforming C implementation.

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


Page 1 of 4  [1] 2 3 4  Next page →

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


csiph-web