On 2025-06-11, Keith Thompson <Keith.S.Thompson+
u@gmail.com> wrote:
Kaz Kylheku <643-408-1753@kylheku.com> writes:
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
Kaz Kylheku <643-408-1753@kylheku.com> writes:
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
I find the reservation of potential errno macro names annoying.
>
If the standard contained /no/ statements about what a given header
file may reserve, then /any/ identifier whatsoever would be a potential
clash.
>
The errno reservation is kind of good because implementors often extend
the set of errno constants. POSIX has a lot more of them than ISO C, and
there are some vendor-specific ones.
>
Anyway, you can safely ignore the reservation theatre, and just
deal with clashes that happen, when they happen. (If you're lucky,
that could just be never).
>
You can do that, but a new clash could happen when your code is
compiled on a system that defines an errno macro that you haven't
seen before.
>
A new CRASH could happen too, and any number of things.
>
Sure, but a compilation failure is more likely.
>
This clash would be literally one of the first roadblocks, if not the
first one, that we would see when just exploring the possibility whether
our code might not run on that system.
>
At that point we could be months away from declaring that a supported
platform.
>
Sure, but why not skip that first roadblock?
Because:
1. The roadblock is not a sure thing; in fact it is improbable.
2. The severity/impact is trivial.
3. There are dowsides to skipping it:
- tiny amount of effort, which occurs with 100% probability.
- giving up a desired name.
Anyway, ISO C, POSIX and vendors have historically introduced new
identifiers in spaces that were not previously declared as reserved.
If you're ever hit by that, you will feel like a completel sucker if
you've religiously adhered to namespaces from your end.
>
Yes, that can happen, but no, I won't feel like a complete sucker.
>
If I define my own strfoo() function and a new edition of the standard
defines strfoo() in <string.h>, the clash is my fault,and I could have
avoided it by defining str_foo().
>
But, my point is, that maybe you could have called it kidneybeans() and
still have a clash.
>
Certainly, I've already acknowledged that.
>
But surely an identifier that the standard says is reserved is less
likely to cause a clash than one that isn't.
The probabilities are not precisely quantified, but low.
The probability that your #define ELMER_FUDD will clash with something
out of <errno.h> is vanishingly low, as is the probability that #define
BUGS_BUNNY will clash with something in spite of not intruding into
a reserved namespace.
We have no way to quantitfy the probabilities, and they are so low that
even if one could be determined to be 100 times the other, why
prioritize the concern over that difference over any other naming
consideration? (Like that maybe Looney Tunes characters aren't very good
In fact, if you are writing new string functions that are the same sort
of stuff like the standard ones, you should use the str prefix,
for consistency.
>
If your code is influential enough, they might be standardized one
day---and then they are ready with the proper naming, so early adopters
of your functions won't have to change anything; just in their build
system drop the third party code and switch to what their library now
provides.
>
I see your point, but ... meh. To me, a name matching "str[a-z]*"
fairly strongly suggests a function declared in <string.h> in ISO C.
Of course it's not an absolute rule; see strlcpy(), for example
(which is now part of POSIX).
Note that the guys who made strlcpy did (almost) exactly what I say
above. They deliberately introduced the function into that namespace,
which made it more nicely 'standardizable". I say almost because they
are systems implementors working on OpenBSD, and so they are using the
namespace as designed. However, the use of those functions spread beyond
OpenBSD; application codebases started defining those for themselves.
Even a str*() identifier that never clashes with ISO C's <string.h>
can still clash with POSIX, or glibc, or BSD, or ....
>
I would have been happier if POSIX were less intrusive on the
C standard library, but the way C and POSIX evolved didn't make
that feasible.
But POSIX has to use *some* kind of names. No matter what you call a
function, it's going to start with either an underscore, or an upper or
lower case letter. So if it doesn't intrude into the _* space, it will
intrude into a*. Or else if not into that one, then b*, ... and so on.
Everything is in some space, and could step on something in an
application.
Religiously sticking to certain spaces can uglify the API. Imagine
everything newer than 1990 in POSIX were called posix_<something>.
Yuck! (The whole pthread_* thing is actually curious that way).
Namespaces offer a solution. They are not available in C, and in many
ways are a solution in search of a problem.
It's amazing how far C development is going, into code bases of millions
of lines and even orders of magnitude more, without a package system.
What helps is that there are no clashes between:
- static symbols in separate translation units.
- symbols in separate programs
- unexported symbols among shared libraries
It's also amazing how just even a small naming convention reduces
the occurrences of clashes. E.g. four letter prefix of your company's
acronym, and you're mostly good. Writing code for Broadcom? Just
call things brcm_*.
Speaking of POSIX, again, if you use ALL_CAPS variable names in shell
scripts, Makefiles, or your environment you are in treading in reserved
namespace! Yet everyone deos this all the time and the sky does not
fall.
Just because POSIX says that it will not define lower-cased environment
varaibles doesn't mean everyone should rush to define their own
variables there.
The "user" and "vendor" roles can be fluid. You might define a
lower cased environment variable, thinking you are a user, in order not
to clash with vendors. Next thing you know, you have users who are
buying a complete system solution for you, including your app with
lower-cased environment variables. You're now "vendor" and doing it
wrong.
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca