Discussion:
Naming conventions
(too old to reply)
Thiago Adams
2016-10-11 11:40:13 UTC
Permalink
Raw Message
I have many functions that have the same meaning and apply for many objects.

For instance:
Init, Destroy, Swap, Delete, Create, Clear

Because of the lack of function overloading I use this pattern:

Object_XXX
Object_Init

I have other functions that may not apply for other object, but I keep the pattern just to avoid more cases.

Do you use some name convention?
How do you solve this "problem"?


I am aware of _Generic but I think it's not solve this problem well because it's centralized.

Should C add function overloading?
BartC
2016-10-11 12:07:24 UTC
Permalink
Raw Message
Post by Thiago Adams
I have many functions that have the same meaning and apply for many objects.
Init, Destroy, Swap, Delete, Create, Clear
These names are /too/ generic to be used globally. But might be OK as
local functions within one module.
Post by Thiago Adams
Object_XXX
Object_Init
I'd use something like that. Certainly some prefix or suffix (perhaps
shorter than 'object') that will link these names to each other.

I assume here that 'Object' is fixed rather than depend on the kind of
object. If all the things being operated on are tagged, then you can have:

void obj_init(object*); // or init_obj
void obj_delete(object*);

and so on. Each can then redirect to a specialised function depending on
the tag. (Or maybe the object contains a function pointer to the
handler, or a pointer a table of functions, and you can start doing
things that way, but that's starting to be too C++-like.)
--
Bartc
Thiago Adams
2016-10-11 12:41:27 UTC
Permalink
Raw Message
Post by BartC
Post by Thiago Adams
I have many functions that have the same meaning and apply for many objects.
Init, Destroy, Swap, Delete, Create, Clear
These names are /too/ generic to be used globally. But might be OK as
local functions within one module.
Post by Thiago Adams
Object_XXX
Object_Init
I'd use something like that. Certainly some prefix or suffix (perhaps
shorter than 'object') that will link these names to each other.
I assume here that 'Object' is fixed rather than depend on the kind of
void obj_init(object*); // or init_obj
void obj_delete(object*);
and so on. Each can then redirect to a specialised function depending on
the tag. (Or maybe the object contains a function pointer to the
handler, or a pointer a table of functions, and you can start doing
things that way, but that's starting to be too C++-like.)
I choose obj_init instead of init_obj because of auto-complete on IDEs. I type obj_ and then "ctrl space" to see what else applies.

I do not consider to use the pointer to function because I think it has overhead.

I think the short names works well for "namespaces" initials for a lib or company. But these functions Init etc, are a different situation and it's hard to find a short name.For instance, what is the short name for Parser_Init?
Jorgen Grahn
2016-10-12 04:49:05 UTC
Permalink
Raw Message
Post by Thiago Adams
I have many functions that have the same meaning and apply for many objects.
Init, Destroy, Swap, Delete, Create, Clear
Object_XXX
Object_Init
I have other functions that may not apply for other object, but I
keep the pattern just to avoid more cases.
Do you use some name convention?
How do you solve this "problem"?
The way you do (but without the capitalization). When your code is
centered around object-like structs, that's IME the conventional way
to do it.

...
Post by Thiago Adams
Should C add function overloading?
That would be very nice, although I don't think it's going to happen.

One of the nice things about C++ is that it's easier to find short
names for things, so there's less "noise" in the code. If a function
should be called read(), you can call it that instead of
myproject_mystruct_read(). Function overloading and namespaces are
the tools for that.

/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
s***@casperkitty.com
2016-10-12 16:10:02 UTC
Permalink
Raw Message
Post by Thiago Adams
Should C add function overloading?
Allowing overloading for non-static functions will cause trouble when linking
code to other modules, since multiple distinct functions in the code may have
the same name; C++ compilers often solve this issue by adding information
about a function's signature to the name, but that makes it much harder for
code from one compiler to interact with code produced elsewhere. Such
problems are cited as one of the reasons why requests to add overloading
have been consistently refused.

A simple solution which would achieve 90% of the benefits of overloading
without requiring any changes to the linking process or the way C code
interacts with other languages would be to allow overloading *only* for
functions declared "static" or "static inline". If a function's name is
never used by anything outside the function, the compiler can assign it
whatever internal name it wants and nothing else in the universe will need
to care about it. That would then allow for:

static inline __overload void open(SESAME *p) { open_sesame(p); }
static inline __overload void open(DOOR *p) { open_door(p); }

etc. The outside world would never see two "open" functions which have
different code, but would merely see "open_sesame" and "open_door". The
source text, however, could use the same name for both purposes.

Does anyone see any disadvantages to such an approach?
Rick C. Hodgin
2016-10-12 16:25:49 UTC
Permalink
Raw Message
Post by s***@casperkitty.com
Does anyone see any disadvantages to such an approach?
CAlive plans to address this in two ways. Rather than name mangling, I
use something called "attributifying," which applies the function's
attributes in fundamental types to its name. This creates a form
which can be read at runtime, which allows overloading. Example:

void myFunc(int, float);

// Attributified as:
myFunc__void__int_float;

Any external request for the "myFunc" can iterate through all
named myFunc* instances, and retrieve the one they desire.

Second, I create a fixed _requestor() function, which can be called
to explicitly reveal details about each function, including source code
parameter names if that information is provided by compile-time or
link-time switches. In this way, enumeration is also possible, but with
far greater details, including even everything known about the
function. This allows even functions which map to the same types
fundamentally under attributifying to still be resolved to their target
address.

I think C needs to support function overloading, and I think it needs
a straight-forward convention like attributifying, a purposeful play on
words to be the exact opposite of mangling.

Best regards,
Rick C. Hodgin
Jerry Stuckle
2016-10-12 20:43:07 UTC
Permalink
Raw Message
Post by Rick C. Hodgin
Post by s***@casperkitty.com
Does anyone see any disadvantages to such an approach?
CAlive plans to address this in two ways. Rather than name mangling, I
use something called "attributifying," which applies the function's
attributes in fundamental types to its name. This creates a form
void myFunc(int, float);
myFunc__void__int_float;
Any external request for the "myFunc" can iterate through all
named myFunc* instances, and retrieve the one they desire.
A slightly different syntax, but the same thing C++ does - and a the
reason given why C does not allow function overloading.
Post by Rick C. Hodgin
Second, I create a fixed _requestor() function, which can be called
to explicitly reveal details about each function, including source code
parameter names if that information is provided by compile-time or
link-time switches. In this way, enumeration is also possible, but with
far greater details, including even everything known about the
function. This allows even functions which map to the same types
fundamentally under attributifying to still be resolved to their target
address.
I'm not sure why this would be needed in a compiled language. An
interpreted language such as Java, yes.
Post by Rick C. Hodgin
I think C needs to support function overloading, and I think it needs
a straight-forward convention like attributifying, a purposeful play on
words to be the exact opposite of mangling.
Best regards,
Rick C. Hodgin
Again - that's what C++ does - and code compiled by one compiler is not
necessarily compatible with code from another compiler.

And no, it is not the exact opposite of mangling. If you know how to
read the mangled name, you can tell what the function name and
parameters are.
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
Thiago Adams
2016-10-13 11:34:17 UTC
Permalink
Raw Message
Post by Rick C. Hodgin
Post by s***@casperkitty.com
Does anyone see any disadvantages to such an approach?
CAlive plans to address this in two ways.
What is CAlive?
Is a new language based on C?
Is it open source?
Is C a subset of CAlive?
What is the current status?
Do you have a FAQ? :)
Rick C. Hodgin
2016-10-13 12:08:50 UTC
Permalink
Raw Message
Post by Thiago Adams
What is CAlive?
Is a new language based on C?
It's a planned new language with features from C, C++, plus new features.
It is a compiler being created with an explicit up-front acknowledgement
of Jesus Christ:

https://groups.google.com/forum/caliveprogramminglanguage
Post by Thiago Adams
Is it open source?
It's a type of public domain license:
http://www.libsf.org/licenses/libsf-pbl-v1.txt
Post by Thiago Adams
Is C a subset of CAlive?
CAlive is very C-like, but it looks to what human beings would expect for
computation, auto-upsizing types for intermediates, and then
sign-saturating min/max values of the target is to small, for example.
It also introduces several new syntax features and flow control support.

I plan to eventually incorporate C90 and C99 compliant support via
compile switches, but that's last on my "CAlive list."
Post by Thiago Adams
What is the current status?
I have almost everything worked through on how to handle syntax
parsing and feature support. There are a handful of things I haven't
yet decided on how best to handle.

I am developing a simple assembler and simple C compiler for use with
my OS kernel. Once those three are functional, I will move to full-
time work on CAlive (James 4:15 ... "Lord willing").
Post by Thiago Adams
Do you have a FAQ? :)
Not really. So far it's only been me interested in the project. Here's the
manual I started, and a text file indicating keywords and features, though
it is getting stale and out of date (RDC is the Rapid Development
Framework that will house the compiler design, CAlive is defining its
abilities, basically):

https://github.com/RickCHodgin/libsf/tree/master/books/rdc
https://github.com/RickCHodgin/libsf/blob/master/exodus/tools/rdc/rdc_specs.txt

-----
It's a ways off, but progress continues to be made. Most of the design work is completed. Now it's just more design
review and coding.

Best regards,
Rick C. Hodgin
Rick C. Hodgin
2016-10-13 12:14:42 UTC
Permalink
Raw Message
Post by Rick C. Hodgin
Post by Thiago Adams
What is CAlive?
Is a new language based on C?
It's a planned new language with features from C, C++, plus new features.
It is a compiler being created with an explicit up-front acknowledgement
https://groups.google.com/forum/caliveprogramminglanguage
Corrected link:

https://groups.google.com/forum/#!forum/caliveprogramminglanguage

Bets regards,
Rick C. Hodgin
Richard Damon
2016-10-15 23:48:26 UTC
Permalink
Raw Message
Post by Rick C. Hodgin
Post by s***@casperkitty.com
Does anyone see any disadvantages to such an approach?
CAlive plans to address this in two ways. Rather than name mangling, I
use something called "attributifying," which applies the function's
attributes in fundamental types to its name. This creates a form
void myFunc(int, float);
myFunc__void__int_float;
Any external request for the "myFunc" can iterate through all
named myFunc* instances, and retrieve the one they desire.
Second, I create a fixed _requestor() function, which can be called
to explicitly reveal details about each function, including source code
parameter names if that information is provided by compile-time or
link-time switches. In this way, enumeration is also possible, but with
far greater details, including even everything known about the
function. This allows even functions which map to the same types
fundamentally under attributifying to still be resolved to their target
address.
I think C needs to support function overloading, and I think it needs
a straight-forward convention like attributifying, a purposeful play on
words to be the exact opposite of mangling.
Best regards,
Rick C. Hodgin
May I as what is different between your 'attributifying' and 'name
mangling' (other than that your method doesn't use any 'compression' to
make the names shorter)?

One big issue you will run into is that I believe C still defines that
two structures in DIFFERENT translation units are compatible, if their
member by member definitions are identical, even if they have different
names, thus the following is totally valid:


file1.C:

struct foo {
int i;
};

int bash(struct foo* ptr) {
return ptr->i;
}


file2.c

struct bar {
int i;
} x;

extern int bash(struct bar*);

int main() {
x.i = 0;
return bash(&x);
}


Note, this does NOT work for C++, where types with different names are
different, so not compatible (this was a needed incompatibility to
handle the name mangling needed for overloading functions).
Tim Rentsch
2016-10-16 00:37:52 UTC
Permalink
Raw Message
[...] I believe C still defines that
two structures in DIFFERENT translation units are compatible, if their
member by member definitions are identical, even if they have
different names [...]
As of C99, structs (or unions, or enums) declared in different
translation units have to use the same tag (or both use no
tag at all) to be eligible for consideration as compatible types.
s***@casperkitty.com
2016-10-17 17:37:08 UTC
Permalink
Raw Message
Post by Tim Rentsch
As of C99, structs (or unions, or enums) declared in different
translation units have to use the same tag (or both use no
tag at all) to be eligible for consideration as compatible types.
Does it provide any practical solution for a programmer who needs to
exchange data between two APIs which are set in stone, and use data
formats which are documented as using bit-for-bit identical
representations but happen to use different names?

Note that using:

void convert_data(struct T1 *dest, struct T2 *src, int n)
{
_Static_assert (sizeof *dest == sizeof *src, "Structures don't match!");
memmove(dest, src, n*sizeof *dest);
}

is not guaranteed to work even in cases where the structures are bit-for-bit
identical, since the Standard would allow implementations to treat the
destination storage as having type T2 (and from what I can tell, gcc will
use that allowance).

In the days before whole-program optimization, the fact that two functions
were in different libraries would have on most implementations served to
prevent compilers from trying to make aliasing presumptions based upon
structure tag names, but if library boundaries are no longer a barrier to
such optimizations, what would be? Or is there simply no way to handle such
things efficiently in strictly-conforming code?
Tim Rentsch
2016-10-18 15:38:36 UTC
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Tim Rentsch
As of C99, structs (or unions, or enums) declared in different
translation units have to use the same tag (or both use no
tag at all) to be eligible for consideration as compatible types.
Does it provide any practical solution for a programmer who needs to
exchange data between two APIs which are set in stone, and use data
formats which are documented as using bit-for-bit identical
representations but happen to use different names? [...]
I have no opinion to offer on that question. I was only
reporting the rule.
Rick C. Hodgin
2016-10-16 09:29:40 UTC
Permalink
Raw Message
Post by Richard Damon
May I as what is different between your 'attributifying' and
'name mangling' (other than that your method doesn't use any
'compression' to make the names shorter)?
It conveys parameters in human readable fundamental types
that do not require some equivalent of [extern "C"] for lookup.
And through the _requestor() function, the actual types are known.

It applies human readable typing to names so external runtime-
linked references can have fullbconfidence they're connecting to the
correct thing.

Best regards,
Rick C. Hodgin
Thiago Adams
2016-10-13 11:31:28 UTC
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Thiago Adams
Should C add function overloading?
Allowing overloading for non-static functions will cause trouble when linking
code to other modules, since multiple distinct functions in the code may have
the same name; C++ compilers often solve this issue by adding information
about a function's signature to the name, but that makes it much harder for
code from one compiler to interact with code produced elsewhere. Such
problems are cited as one of the reasons why requests to add overloading
have been consistently refused.
A simple solution which would achieve 90% of the benefits of overloading
without requiring any changes to the linking process or the way C code
interacts with other languages would be to allow overloading *only* for
functions declared "static" or "static inline". If a function's name is
never used by anything outside the function, the compiler can assign it
whatever internal name it wants and nothing else in the universe will need
static inline __overload void open(SESAME *p) { open_sesame(p); }
static inline __overload void open(DOOR *p) { open_door(p); }
etc. The outside world would never see two "open" functions which have
different code, but would merely see "open_sesame" and "open_door". The
source text, however, could use the same name for both purposes.
Does anyone see any disadvantages to such an approach?
I liked.
I think this solution is much like _Generic but it's not centralized in one point and doesn't require macros.

// Possible implementation of the tgmath.h macro cbrt

#define cbrt(X) _Generic((X), \
long double: cbrtl, \
default: cbrt, \
/*for clang*/ const float: cbrtf, \
float: cbrtf \
)(X)


static inline __overload long double cbrt(long double v) { return cbrtl(v); }

static inline __overload float open(float v) { return cbrtf(p); }

Compiler has to collect the alternatives, if no one matches then an error with all alternatives found is presented.

I think to keep it simple the rules to find the correct overload must be simple, having to have two functions const float, float for instance.


I think one keyword is enough and they implies inline.

__overload float open(float v) { return cbrtf(p); }
Thiago Adams
2017-04-26 21:38:00 UTC
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Thiago Adams
Should C add function overloading?
Allowing overloading for non-static functions will cause trouble when linking
code to other modules, since multiple distinct functions in the code may have
the same name; C++ compilers often solve this issue by adding information
about a function's signature to the name, but that makes it much harder for
code from one compiler to interact with code produced elsewhere. Such
problems are cited as one of the reasons why requests to add overloading
have been consistently refused.
A simple solution which would achieve 90% of the benefits of overloading
without requiring any changes to the linking process or the way C code
interacts with other languages would be to allow overloading *only* for
functions declared "static" or "static inline". If a function's name is
never used by anything outside the function, the compiler can assign it
whatever internal name it wants and nothing else in the universe will need
static inline __overload void open(SESAME *p) { open_sesame(p); }
static inline __overload void open(DOOR *p) { open_door(p); }
etc. The outside world would never see two "open" functions which have
different code, but would merely see "open_sesame" and "open_door". The
source text, however, could use the same name for both purposes.
Does anyone see any disadvantages to such an approach?
I realized a solution already exists.
It's the extern "C" in C++.

extern "C" declares the exported names.
It's the opposite of your suggestion that was mark the internal ones as __overload . Your suggestion is more compatible with exiting code of course.

But I guess the function don't need to be only static or inline.
The consequence is if you mark it as __overload is that the function will have name mangling.

In simple words, __overload will turn on name mangling.
s***@casperkitty.com
2017-04-26 23:44:01 UTC
Permalink
Raw Message
Post by Thiago Adams
It's the extern "C" in C++.
extern "C" declares the exported names.
It's the opposite of your suggestion that was mark the internal ones as __overload . Your suggestion is more compatible with exiting code of course.
But I guess the function don't need to be only static or inline.
The consequence is if you mark it as __overload is that the function will have name mangling.
In simple words, __overload will turn on name mangling.
The C++ syntax for [extern "C"] indicates that functions should be exported
with the same names as given in the source. A more generally-useful feature
would be to allow explicit control of exported names, with the caveat that
implementations would only be required to support names of the forms defined
in the Standard. If a linker were to allow names containing e.g. question
marks, and the C grammar were to extended to allow an extern declaration
to include a string literal before an identifier to specify the exported
name, then C code could use something like:

extern int "this?that" widget;

to attach C identifier "widget" to linker symbol "this?that". Programmers
who use such a construct would be responsible for ensuring that any such
names do not conflict with any names that might be used by the implementation.

In general, it is not expected that all C++ compilers for a given platform
will implement name mangling in compatible fashion, and indeed in many cases
they are encouraged *not* to attempt to do so unless they also use compatible
representations for things like virtual-dispatch tables, exception-related
metadata, etc. The [extern "C"] directive serves not only to prevent name
mangling, but also to prevent a compiler from generating anything that would
require outside code to know about a compiler's inner workings.
Chad
2017-04-27 08:26:34 UTC
Permalink
Raw Message
CAlive is vaporware.
Rick C. Hodgin
2017-04-27 10:38:20 UTC
Permalink
Raw Message
Post by Chad
CAlive is vaporware
"Happy vapor to you.
Happy vapor to you.
Happy vapor, dear Chad.
Happy vapor to you.
(and many more)"

Thank you,
Rick C. Hodgin

PS - "We're on vapor, Cougar."

Loading...