[net.unix-wizards] Naming Conventions for System Libraries

idallen (09/13/82)

How can the C programmer avoid accidentally re-defining an existing C
Library function, making it unusable by other C Library functions that
need it?  How can the programmer avoid accidentally re-defining or
using an external needed by the Library?

For example, if the programmer didn't know that getlogin() used
ttyslot(), s/he might accidentally redefine ttyslot() to be something 
peculiar.  Then getlogin() would fail.  Similarly, an accidental
re-definition of _doprnt() would render printf() useless.

Currently, the only way to avoid this problem is to remember ALL
function and external names used in the library, and to avoid these
names in our programs.  It is probably too late to change the way
things work with the existing C library; this is an appeal to future
language designers.

Somewhere in C history, all the C Library function names should have
been renamed to include some special character (or have some special
naming convention).  Programmers should have been told that this
special convention was used to name C Library routines, and that they
were NOT to use any externals or function names that used this
convention (unless they were specifically replacing the C Library
function with their own).

If this convention, or a similar one, were followed, programmers would
never need to worry about accidentally replacing C library functions with
their own.  This is the *only* way programmers can avoid accidentally
replacing *future* library functions.

A special character convention would allow names like:

   $printf()   str$len()   get$uid()   get$pwent()   ...

(For the B Language used here at Waterloo, we chose the period as our
special character.  All B Library function names contain a period.)

I don't know if there are any free characters in the C character set
that would allow this change to take place.  The underscore would be a
good-looking character to use, but it's probably been used a lot by
people already.  Adopting a convention that all library names should
*start* or *end* with a character (e.g. Xprintf) doesn't appeal to me.

The next time a library-based language gets built, I hope someone
thinks of the memory burden of the programmer.

	-IAN!   U of Waterloo   (decvax!watmath!idallen)

eric (09/14/82)

Lint will detect the redefinition of library functions.
The problem is many people, including myself, don't use lint regularly.
I'd like to see this feature of lint (and some others) moved into the C compiler.
(your example of redefining _doprnt isn't valid, the prefix _ has
been conventionally used for `secret' global names.)

I don't think your `special character' scheme will work well.
You can't assume there is going to be only one system library.
A user might need to use several independently-developed librarys,
for example, graphics, fast file system, stdio, etc.
There's some use of prefixes in the C library: str in strcmp, strcpy;
f in fopen, fread; but it's not consistent: getc, not fgetc.
System calls don't use prefixes and also tend to be very common
identifiers (open, read, time). These should certainly have
been prefixed; application programmers shouldn't have to know
about the existence of most of them when using stdio.

Ada has done a good job of supporting independent librarys,
which they've termed packages. Normally one refers to a package
element by prefixing the package name with a dot operator.
You could have packages `io' and `gr'. A function `open' in both
packages is referred to by io.open and gr.open. There's a statement
to make all package elements local symbols, so that you can leave
off the prefix. This could cause conflicts, but the compiler
should detect them (or you could avoid this language feature).

If you have a C-ld with long symbols names, there's no reason
you can't use prefixes (io_open is better that fopen though).
If you have the resources, you could even change the C library
source and documentation to use this convention.

			Eric Gisin, decvax!watmath!watarts!eric.

gwyn@Brl@sri-unix (09/21/82)

From:     Doug Gwyn <gwyn@Brl>
Date:     17 Sep 82 5:04:45-EDT (Fri)
The usual solution to your problem is to declare your own routines
"static".  That way they're not known to the linker.

Of course this doesn't solve the problem of entry points in a
multi-file program conflicting with library names.  In this
case the only recourse is to check each of your externally-
accessible interface routines (there shouldn't be too many)
against the appropriate library namelists.

Sometimes it is actually useful to be able to replace a system
library routine by one's own version, so there are positive aspects
to the design too.

A complete solution to the problem requires substantial support from
the linker.  Try talking IBM or DEC into this and see what happens!

mullen@Nrl-Css@sri-unix (09/22/82)

From: mullen at Nrl-Css (Preston Mullen)
Date: 17 Sep 1982 12:03:29-EDT
The 4.1bsd C compiler allows '$' as a character in identifiers
(it's a "letter").  The C preprocessor does too.  I can't recall
ever seeing this fact documented.

P.S.  Certain 4.1bsd programs, e.g. ctags and vgrind, do not know
this and hence behave strangely when function names include '$'.

dan@Bbn-Unix@sri-unix (09/22/82)

From: Dan Franklin <dan@Bbn-Unix>
Date: 17 Sep 1982 13:01:14 EDT (Friday)
This is a good point.  UNIX is actually quite unusual
in not having such a standard prefix for system names.
As a matter of C trivia, there are three printing ASCII
characters not used anywhere in the language: dollarsign,
at-sign, and backquote. Dollarsign seems like a reasonable
choice for such a separator.

idallen (09/22/82)

Having to check every one of my own function names against an existing
library namelist only works for the current version of the library.
If the system library changes, it might well change to use some function
or external name that I use in my program.  A naming convention is the
only way to avoid *future* naming conflicts.

minow (09/23/82)

Vax-11 C and Decus C both allow '$' freely in identifiers.  This is
needed to access VMS system library functions.  Decus C maps '_' to
(radix-50) '.' in external symbols.  This letter is, however, reserved
for operating-system globals (such as those in the RSX-11M file service
library), so '_' has been eliminated from the library wherever possible.

For example, _doprnt() has been named $$dopn.

While I'm on the subject, there are a few useful library routines in
Decus C which I would recommend for inclusion on Unix:

fgetname(iop, char_buffer)	Writes the name used to fopen() the
				FILE *iop argument.  This is implemented
				on Vax-11C, along with getname(chan, buffer).

fwild(file_name, open_mode)	Sets up the file system to open a wild-card
				file.  Returns a FILE *.  The next file is
				opened by calling fnext(iop).

isalloc(mem_ptr)		TRUE if mem_ptr was allocated by malloc().
msize(mem_ptr)			The number of bytes allocated (undefined
				if isalloc(mem_ptr) is FALSE).

Fwild/fnext would typically be used as follows:

	int	nfiles;
	FILE	*fd;

	if ((fd = fwild("foo.*", "r")) == NULL) {
		perror("foo.*");
		exit(1);		/* Couldn't parse/setup file	*/
	}
	for (nfiles = 0; fnext(fd) != NULL; nfiles++) {
		fgetname(fd, file_name);	/* Currently open file	*/
		/* Normal processing of fd using getc, fgets, etc.	*/
	}
	if (nfiles == 0)
		printf("No files matching foo.*\n");

Fwild/fnext is fairly simple to implement on VMS, RSTS, and RSX, fairly
painful on RT11.  I have no idea whether it is even possible on Unix
(but you could always fork a shell, feed it the file name, pass that
through echo, and build a table of the matches).

Martin Minow
decvax!minow

henry (09/23/82)

There are two possible problems with using '$' as a character in
identifiers to mark them as "system" names.  The first is that it
is likely to foul up things like yacc, which process C text looking
for $ as a marker for special hooks into their innards.  The second,
decidedly more serious problem, is that...

		it's not C, folks.

No matter what Berkeley says.  It's neither standard nor portable.

I can't say I'm too delighted with a lot of the other things Berkeley
has done, but dammit, they should have kept their hands off the C
language!  As Dennis Ritchie has been heard to say, "we *had* a
standard...".

					Henry Spencer
					U of Toronto

dave (09/26/82)

Beginning secret library routines with a capital letter has been used
here for a long time, and seems to work. For example, our graphics package
uses G (Ginit, Gclose, etc.). Obviously it's a good idea for package
writers to pick a letter not used by any packagesl likely to be linked
together with the package being created.
Dave Sherman
CSRG
U of Toronto