Path: csiph.com!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: encapsulating directory operations Date: Tue, 10 Jun 2025 13:35:19 -0700 Organization: None to speak of Lines: 83 Message-ID: <878qlzibco.fsf@nosuchdomain.example.com> References: <100h650$23r5l$1@dont-email.me> <20250520065158.709@kylheku.com> <100i2la$292le$1@dont-email.me> <87a5770xjw.fsf@nosuchdomain.example.com> <100j09o$2f04b$1@dont-email.me> <87tt5ezx9y.fsf@nosuchdomain.example.com> <100j4t3$2foah$1@dont-email.me> <87ldqqzfj0.fsf@nosuchdomain.example.com> <100kak8$2q0s6$1@dont-email.me> <87a575zvmb.fsf@nosuchdomain.example.com> <100o3sc$3ll6t$1@dont-email.me> <87bjrkxonr.fsf@nosuchdomain.example.com> <87iklrtcys.fsf@nosuchdomain.example.com> <864ixavbs4.fsf@linuxsc.com> <87plfys9a5.fsf@nosuchdomain.example.com> <86bjqvr3u5.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Tue, 10 Jun 2025 22:35:20 +0200 (CEST) Injection-Info: dont-email.me; posting-host="70286cb1a1338bdee264d7b5452452ec"; logging-data="1560755"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18ru9rci2xQp1/JebT88MQV" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:NdOOENRuvH+h9VYSg/5COcMdsuA= sha1:sDPdZZzushup8KICkw9MOYAJ5b4= Xref: csiph.com comp.lang.c:393797 Tim Rentsch writes: > Keith Thompson writes: >> Tim Rentsch writes: >>> Keith Thompson writes: >>>> Richard Harnden writes: >>>>> On 22/05/2025 23:32, Keith Thompson wrote: >> [...] >> >>>>>> In one of your library's headers: >>>>>> extern const char ESCAPE; >>>>>> In the corresponding *.c file: >>>>>> const char ESCAPE = ('z' - 'a' == 25 ? '\x1b' : '\x27'); >>>>>> Change the name if you prefer. >>>>> >>>>> Wouldn't that be a reserved identifier? >>>> >>>> Yes, it would. Good catch. >>>> >>>> (Identifiers starting with E followed by either a digit or an >>>> uppercase letter are reserved; they could be defined as macros >>>> in .) >>> >>> They are reserved only as macros, and only if has >>> been #include'd. >>> >>> For this particular use, it's easy to make the definition work, >>> simply by adding >>> >>> #undef ESCAPE >>> >>> before the declaration in the header file, and before the >>> definition in the source file (assuming of course that if >>> there are any #include they precede the #undef's). >> >> It would be even easier to pick a different name. > > The point of my comment was to help explain the rules about what > macro names are reserved and under what circumstances, not to > suggest a way to avoid conflicts. And the point of my comment was to suggest a way to avoid conflicts. > A better way to avoid conflicts with E* macros is to take functions > where errno is needed, as for example signal(), and not call them > directly but rather wrap each one in a function, with the wrapping > functions put in (one or more) separate translation unit(s). Those > translation units, and only those translation units, are the ones > where a #include is done. Some details are needed to keep > the separation complete, but I think those aren't too hard to work > out, so if someone has trouble please ask. This way most of the > program can use names beginning with E that might otherwise be > reserved, without any fear of conflicts. There is a bit of source > code overhead, but that is paid only once, across all projects that > use this approach. Also there are some other benefits, related to > libraries used that are not part of ISO C, such as Posix, which > again should be readily apparent to anyone used to working in large > projects that use such libraries. That doesn't strike me as better. You're suggesting a substantial reorganization to avoid some simple name conflicts (identifiers starting with 'E'). I find it much easier -- and yes, better -- to avoid defining identifiers starting with 'E'. (Actually only identifiers starting with 'E' followed by either a digit or an uppercase letter are reserved. It's simpler to avoid all identifiers starting with 'E', but you can safely use something like "Escape" if you like.) If there are other reasons for such an organization, that's fine. (My personal policy is to assume a more expansive set of reserved identifiers, because it means I only have to remember a simpler set of rules. For example, I find it easier to avoid defining any identifiers starting with '_' than to account for the rules for which _* identifiers are reserved for which purposes in which contexts. Of course I'll look up and apply the actual rules when I need to.) I find the reservation of potential errno macro names annoying. Using and reserving identifiers starting with "E_", for example, would have been less intrusive. But we're stuck with it. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */