alternate function names

G

Guest

This question is borderline between language and programming, but I want to
focus more on the language standards issue, rather than the programming issue,
so I am posting here.

I have a number of functions which are front-ended by macros which make some
changes in the way the functions are called. There are various things being
done, but one simple example would be a function that takes a variable number
of (const char *) arguments and joins all the strings together into a single
string, where a NULL is the sentinel at the end of the arguments. The macro
front end adds that NULL so the calling program is less cluttered with detail.

What I have been doing with this is giving the macro the interface name and
naming the function slightly different. I have been putting a "_" in front
of the function name, which I want to get away from doing. So I have a macro
like:
#define strjoin(a...) (_strjoin(a,((const char*)(NULL))))
and a function definition like:
char *_strjoin(const char *s,...)

The alternative I'm looking at is to just use the same name for both macro
and function, like:
#define strjoin(a...) ((strjoin)(a,((const char*)(NULL))))
and:
char *(strjoin)(const char *s,...)

This approach works, but I'm worried about confusion it may cause. So what I
want to do here is see if there is a better alternative to using a different
function name than the one shown above. Would lots of "_" characters help
avoid conflicts? Like maybe:
#define strjoin(a...) (__strjoin__(a,((const char*)(NULL))))
and:
char *__strjoin__(const char *s,...)
 
M

Morris Dovey

Phil...

Frankly, I'd rather code the NULL; and if I were a maintainer I
would prefer to see the NULL than spend time puzzling over a macro.

BTW, identifiers beginning with underscores or with "str" are
reserved. My multi-string concatenator started out as strs() and
became rtss() for this reason. )-:
 
G

Guest

| Frankly, I'd rather code the NULL; and if I were a maintainer I
| would prefer to see the NULL than spend time puzzling over a macro.

I hold the opposite view. But if I were to find a suitable alternate name
for the function itself, you could code direct function calls and use the
NULL. I find it a big pain. My library is intended to remove many of the
pains in programming while still giving me C level access.


| BTW, identifiers beginning with underscores or with "str" are
| reserved. My multi-string concatenator started out as strs() and
| became rtss() for this reason. )-:

I already have a huge number of string functions. But one thing they all
do have is they begin with "str_" (the example I previously posted did not
show a real name from that library). I think it is more important to have
recognizable and understandable names for functions. I would not have
guessed what rtss() is even about without you saying so. So what did you
do, just reverse "str" to "rts" for everything?

Footnote 146 in the last draft for C99 shows usage of an identifier that
is reserved (7.1.3). What it's doing is hiding the reserved usage. So it
would seem to imply that such reservations do not apply behinds the scenes.
But it's unclear if this is an implemention C, or an implemention of something
in C.
 
S

Simon Biber

| BTW, identifiers beginning with underscores or with "str" are
| reserved. My multi-string concatenator started out as strs() and
| became rtss() for this reason. )-:

I already have a huge number of string functions. But one thing
they all do have is they begin with "str_" (the example I previously
posted did not show a real name from that library).

Actually, "str_" is OK. The str prefix is only reserved when followed
by a lowercase letter.

Reserved identifiers include:

is[abcdefghijklmnopqrstuvwxyz]*
to[abcdefghijklmnopqrstuvwxyz]*
cerf
cerfc
cexp2
cexpm1
clog10
clog1p
clog2
clgamma
ctgamma
cerf[fl]
cerfc[fl]
cexp2[fl]
cexpm1[fl]
clog10[fl]
clog1p[fl]
clog2[fl]
clgamma[fl]
ctgamma[fl]
E[0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ]*
PRI[abcdefghijklmnopqrstuvwxyzX]*
SCN[abcdefghijklmnopqrstuvwxyzX]*
LC_[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*
SIG[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*
SIG_[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*
int*_t
uint*_t
INT*_MAX
INT*_MIN
INT*_C
UINT*_MAX
UINT*_MIN
UINT*_C
str[abcdefghijklmnopqrstuvwxyz]*
mem[abcdefghijklmnopqrstuvwxyz]*
wcs[abcdefghijklmnopqrstuvwxyz]*
 
M

Morris Dovey

On Tue, 09 Dec 2003 13:09:56 -0600 Morris Dovey

| Frankly, I'd rather code the NULL; and if I were a
| maintainer I would prefer to see the NULL than spend time
| puzzling over a macro.

I hold the opposite view. But if I were to find a suitable
alternate name for the function itself, you could code direct
function calls and use the NULL. I find it a big pain. My
library is intended to remove many of the pains in programming
while still giving me C level access.

Understandable - in my case I seem to have spent too much of my
career cleaning up other peoples' messes. It's been a real PIA to
run into (really messy) macro definitions that I need to
understand to eliminate as a contributor to the current mess; and
too often the problem has at least involved one of these macros.
| BTW, identifiers beginning with underscores or with "str"
| are reserved. My multi-string concatenator started out as
| strs() and became rtss() for this reason. )-:

I already have a huge number of string functions. But one
thing they all do have is they begin with "str_" (the example
I previously posted did not show a real name from that
library). I think it is more important to have recognizable
and understandable names for functions. I would not have
guessed what rtss() is even about without you saying so. So
what did you do, just reverse "str" to "rts" for everything?

I think nearly everyone eventually has a similar collection. In
my case, I did just what you inferred: I turned all the 'stirs'
into 'rats' (str --> rts). Visit http://www.iedu.com/mrd/c for a
representative sampling of the ugly naming.
Footnote 146 in the last draft for C99 shows usage of an
identifier that is reserved (7.1.3). What it's doing is
hiding the reserved usage. So it would seem to imply that
such reservations do not apply behinds the scenes. But it's
unclear if this is an implemention C, or an implemention of
something in C.

For more than you'd ever want to know about the subject, do a
Google groups search in comp.lang.c on "reserved str" (without
quotes) and prepare to see this beaten to death ( repeatedly :)

I adopted the attitude that since clients see my code I wouldn't
embarrass myself more than absolutely necessary. I changed the
names (growling all the while).
 
J

J. J. Farrell

This question is borderline between language and programming, but I want to
focus more on the language standards issue, rather than the programming issue,
so I am posting here.

I have a number of functions which are front-ended by macros which make some
changes in the way the functions are called. There are various things being
done, but one simple example would be a function that takes a variable number
of (const char *) arguments and joins all the strings together into a single
string, where a NULL is the sentinel at the end of the arguments. The macro
front end adds that NULL so the calling program is less cluttered with detail.

What I have been doing with this is giving the macro the interface name and
naming the function slightly different. I have been putting a "_" in front
of the function name, which I want to get away from doing. So I have a macro
like:
#define strjoin(a...) (_strjoin(a,((const char*)(NULL))))
and a function definition like:
char *_strjoin(const char *s,...)

The alternative I'm looking at is to just use the same name for both macro
and function, like:
#define strjoin(a...) ((strjoin)(a,((const char*)(NULL))))
and:
char *(strjoin)(const char *s,...)

This approach works, but I'm worried about confusion it may cause. So what I
want to do here is see if there is a better alternative to using a different
function name than the one shown above. Would lots of "_" characters help
avoid conflicts? Like maybe:
#define strjoin(a...) (__strjoin__(a,((const char*)(NULL))))
and:
char *__strjoin__(const char *s,...)

I've often seen the macro named as the upper-case version of the function,
so STRJOIN in your case. This is used to imply "essentially the same as
the function, but doing some fiddling about first before either providing
similar functionality or actually calling the function". It gives a clear
hint that it's probably related to the function, but also makes clear that
there must be something different about it.

You shouldn't be using tokens beginning with underscore, or with 'str'
followed by a lower case letter - they're reserved for the implementation.
There are rules about exactly when they are reserved, but it's simplest
to avoid them altogether.
 
D

Derk Gwen

# What I have been doing with this is giving the macro the interface name and
# naming the function slightly different. I have been putting a "_" in front
# of the function name, which I want to get away from doing. So I have a macro
# like:

You can have a function name the same as a #define with arguments. Parenthesise
the function name but not the #define:

#define xyzzy(parrot) (xyzzy)(parrot-2,parrot+2)
int (xyzzy)(int plugh,int plover);
int (xyzzy)(int plugh,int plover) {
return plugh*plover;
}

int main(int argc,char **argv) {
printf("%d\n",(xyzzy)(4,8));
printf("%d\n",xyzzy(6));
return 0;
}

# #define strjoin(a...) (_strjoin(a,((const char*)(NULL))))
# and a function definition like:
# char *_strjoin(const char *s,...)
#
# The alternative I'm looking at is to just use the same name for both macro
# and function, like:
# #define strjoin(a...) ((strjoin)(a,((const char*)(NULL))))
# and:
# char *(strjoin)(const char *s,...)
#
# This approach works, but I'm worried about confusion it may cause. So what I
# want to do here is see if there is a better alternative to using a different

As long as you use #defines with arguments and parenthesise the function name,
there will be no confusion in the compiler. (If you look at some of your
implementation standard headers, you'll see them doing this trick.) Whether
it confuses other programmers is a different issue.
 
G

Guest

| Actually, "str_" is OK. The str prefix is only reserved when followed
| by a lowercase letter.

OK, glad to hear that.


| Reserved identifiers include:

Do you have a citation? A C99 section number would do. I didn't see
it directly the way I searched, but maybe I missed an interpretation
of different parts in different places apart from each other.


| is[abcdefghijklmnopqrstuvwxyz]*

I have a few is_* names.


| str[abcdefghijklmnopqrstuvwxyz]*
| mem[abcdefghijklmnopqrstuvwxyz]*

And a few mem_* as well.
 
G

Guest

| Understandable - in my case I seem to have spent too much of my
| career cleaning up other peoples' messes. It's been a real PIA to
| run into (really messy) macro definitions that I need to
| understand to eliminate as a contributor to the current mess; and
| too often the problem has at least involved one of these macros.

Well, I hope that ultimately, my code won't need to be cleaned up.

*knocks on wood* :)


| I think nearly everyone eventually has a similar collection. In
| my case, I did just what you inferred: I turned all the 'stirs'
| into 'rats' (str --> rts). Visit http://www.iedu.com/mrd/c for a
| representative sampling of the ugly naming.

OK, you showed yours, I'll show mine:
http://libh.slashusr.org/source/string/src/lib/h/

The main library page is just:
http://libh.slashusr.org/


| For more than you'd ever want to know about the subject, do a
| Google groups search in comp.lang.c on "reserved str" (without
| quotes) and prepare to see this beaten to death ( repeatedly :)

Being one to try things differently than told to do, I used the quotes :)
Your post came in number 2 (searched by relevance mode). The first one
that came up clarified a lot.
 
G

Guest

| I've often seen the macro named as the upper-case version of the function,
| so STRJOIN in your case. This is used to imply "essentially the same as
| the function, but doing some fiddling about first before either providing
| similar functionality or actually calling the function". It gives a clear
| hint that it's probably related to the function, but also makes clear that
| there must be something different about it.

I used to do that back when I didn't use macros very much. Now I use them
quite a lot. Many are front ends to functions. Many are just used on their
own without a function behind the scenes. I program using these functions
and macros a lot. And I've found code with so much UPPER CASE ALL OVER is
harder to read. Now I'm thinking more in terms of API design regardless of
whether I implement as macro or function.


| You shouldn't be using tokens beginning with underscore, or with 'str'
| followed by a lower case letter - they're reserved for the implementation.
| There are rules about exactly when they are reserved, but it's simplest
| to avoid them altogether.

Avoiding the beginning with underscore is the motivation of my original post
for this thread. My example of strjoin() was a bad choice of name. The
actual function is called str_dup_arg() because there are other variations
that do things like copy or append to a target, and accept strings in forms
like an array of pointers. You can view the actual source, still with the
leading underscore on the function name (which hopefully by the next version
will be changed), here:
http://libh.slashusr.org/source/string/src/lib/h/str_dup_arg.c
That whole section (string) is being majorly changed, which inspired this
issue in the first place. Next version will be quite different.
 
G

Guest

| # What I have been doing with this is giving the macro the interface name and
| # naming the function slightly different. I have been putting a "_" in front
| # of the function name, which I want to get away from doing. So I have a macro
| # like:
|
| You can have a function name the same as a #define with arguments. Parenthesise
| the function name but not the #define:
|
| #define xyzzy(parrot) (xyzzy)(parrot-2,parrot+2)
| int (xyzzy)(int plugh,int plover);
| int (xyzzy)(int plugh,int plover) {
| return plugh*plover;
| }

Yes, that is being considered. And a lot of my functions already do that.
But I'm trying to decide if that will confuse people or not. That issue
I consider to not be a comp.lang.c question, and was planning to ask that
on comp.programming instead. But to keep my options open, what I wanted
to know from comp.lang.c was a suitable alternative to putting underscore
in front of the name.


| int main(int argc,char **argv) {
| printf("%d\n",(xyzzy)(4,8));
| printf("%d\n",xyzzy(6));
| return 0;
| }

Things like this could be the confusion I want to avoid.


| As long as you use #defines with arguments and parenthesise the function name,
| there will be no confusion in the compiler. (If you look at some of your
| implementation standard headers, you'll see them doing this trick.) Whether
| it confuses other programmers is a different issue.

And I have already done this in some functions. But now I want to get all my
functions to be one way or the other, and hence the need to make a decision.
 
I

Irrwahn Grausewitz

| Reserved identifiers include:
Do you have a citation? A C99 section number would do. I didn't see
it directly the way I searched, but maybe I missed an interpretation
of different parts in different places apart from each other.

ISO/IEC 9899:1999
7.26.*
7.1.3
6.11.9
6.10.8
6.4.1

Regards
 
D

Dan Pop

In said:
Phil...

Frankly, I'd rather code the NULL; and if I were a maintainer I
would prefer to see the NULL than spend time puzzling over a macro.

BTW, identifiers beginning with underscores or with "str" are
reserved. My multi-string concatenator started out as strs() and
became rtss() for this reason. )-:

Only identifiers beginning with str followed by a lower case letter are
reserved, so you could have used str_s() insteat of the rtss()
abomination.

Dan
 
S

Simon Biber

Phil Howard said:
| Reserved identifiers include:

Do you have a citation? A C99 section number would do. I didn't
see it directly the way I searched, but maybe I missed an
interpretation of different parts in different places apart from
each other.

I generated that list directly from C99 7.26.*
| is[abcdefghijklmnopqrstuvwxyz]*

I have a few is_* names.

Which are fine, as is* are only reserved when followed by a
lowercase letter.
| str[abcdefghijklmnopqrstuvwxyz]*
| mem[abcdefghijklmnopqrstuvwxyz]*

And a few mem_* as well.

Ditto.
 
M

Morris Dovey

Dan said:
Only identifiers beginning with str followed by a lower case letter are
reserved, so you could have used str_s() insteat of the rtss()
abomination.

Of course. Abomination, like beauty, is in the eye of the
beholder. To this beholder, artificially expanding identifiers
without adding semantic content is another abomination, because
it "spoils" formatting efforts and helps to deplete my personal
supply of newlines, tabs, and spaces. (-8

It /is/ an aesthetic issue. Once the requirement to "uglify" a
collection of functions (more than four dozen, most of which
pre-dated any C standard) was recognized, it was a matter of
choosing the /least/ abominable path.

It was made still more irritating by the near certainty that the
standard library would never be expanded in such a way as to
produce name conflicts - that the reservation of str* and to* was
done "because we can" and not "because it's essential" - and
because the committee opted for "certain wholesale breakage now"
rather than "possible retail breakage in the future" - a kind of
decision making that strikes me as unwise and destructive, no
matter how well-intended it might have been.

[I already know that /everyone's/ mileage varies on this issue.]
 
D

Dan Pop

In said:
Of course. Abomination, like beauty, is in the eye of the
beholder. To this beholder, artificially expanding identifiers
without adding semantic content is another abomination, because
it "spoils" formatting efforts and helps to deplete my personal
supply of newlines, tabs, and spaces. (-8

It's choosing the lesser evil. str_s is meaningful to anyone, rtss is
meaningful to the insider only. No one would guess that rts is the
reverse of the intended prefix and, therefore, the rtss identifier is as
cryptical as you can get.

Then again, if you write code for your own aesthetical gratification...

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top