Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Re: Splitting a source code file (http://www.velocityreviews.com/forums/t724640-re-splitting-a-source-code-file.html)

Ben Pfaff 06-02-2010 05:22 PM

Re: Splitting a source code file
 
cri@tiac.net (Richard Harter) writes:

> What I would like
> to do is split the file. Part I goes into an include file.
> Parts I and II (public and private) go into separate files. The
> issue is how to make the private functions in file II visible to
> the public functions in file I.
>
> One way to do this is to create a struct that holds pointers to
> all of the private functions. A more elaborate scheme declares
> function pointer variables in the part I file and has behind the
> scene code to copy the actual function pointers from the part II
> file into the part I file.


I would use a function naming convention that makes it possible
to easily distinguish public and private functions. You could
use, for example, a special prefix or suffix to do. (I often use
a __ suffix to denote private functions.) Then I would put the
prototypes for the private functions into a separate include file
also named distinctly, e.g. using "-private.h" as suffix.

It sounds like far too much work to me to use function pointers
for this. Do you distrust the clients of the code so much?
--
"This is a wonderful answer.
It's off-topic, it's incorrect, and it doesn't answer the question."
--Richard Heathfield

Ben Pfaff 06-02-2010 07:16 PM

Re: Splitting a source code file
 
cri@tiac.net (Richard Harter) writes:

> On Wed, 02 Jun 2010 10:22:55 -0700, blp@cs.stanford.edu (Ben
> Pfaff) wrote:
>
>>cri@tiac.net (Richard Harter) writes:
>>
>>> What I would like
>>> to do is split the file. Part I goes into an include file.
>>> Parts I and II (public and private) go into separate files. The
>>> issue is how to make the private functions in file II visible to
>>> the public functions in file I.
>>>
>>> One way to do this is to create a struct that holds pointers to
>>> all of the private functions. A more elaborate scheme declares
>>> function pointer variables in the part I file and has behind the
>>> scene code to copy the actual function pointers from the part II
>>> file into the part I file.

>>
>>I would use a function naming convention that makes it possible
>>to easily distinguish public and private functions. You could
>>use, for example, a special prefix or suffix to do. (I often use
>>a __ suffix to denote private functions.) Then I would put the
>>prototypes for the private functions into a separate include file
>>also named distinctly, e.g. using "-private.h" as suffix.

>
> I could do that, of course, but there are issues unless I am
> missing something clever. One issue is that we are still
> polluting the name space. Suppose we have three parties, user,
> you and me. You have a package of spiffy stuff nicely wrapped up
> in a library, and so do I. User wants to use our two libraries
> in her application. Unfortunately, we both think that connect is
> an appropriate name for a function. It's private so we both call
> it __connect. Bad news at link time. Now user doesn't want to
> scramble through our code to eliminate the conflict - in fact she
> might not even have the source code at hand.


__connect is a lousy name, of course. But that won't happen if
you pick a proper prefix for your functions and use it to all of
them, even the "private" ones. Suppose your library is libfoo.
Public functions might be named foo_<name> and private functions
foo_<name>__. There will be no collisions, even for private
functions, as long as no other library also uses foo_ as its
prefix.

There are also implementation-specific techniques for avoiding
the problem, for example ELF symbol visibility features available
through GCC as described at the bottom of this page:
http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}

Ersek, Laszlo 06-02-2010 07:18 PM

Re: Splitting a source code file
 
On Wed, 2 Jun 2010, Ben Pfaff wrote:

> cri@tiac.net (Richard Harter) writes:
>
>> What I would like to do is split the file. Part I goes into an include
>> file. Parts I and II (public and private) go into separate files. The
>> issue is how to make the private functions in file II visible to the
>> public functions in file I.
>>
>> One way to do this is to create a struct that holds pointers to all of
>> the private functions. A more elaborate scheme declares function
>> pointer variables in the part I file and has behind the scene code to
>> copy the actual function pointers from the part II file into the part I
>> file.

>
> I would use a function naming convention that makes it possible to
> easily distinguish public and private functions. You could use, for
> example, a special prefix or suffix to do. (I often use a __ suffix to
> denote private functions.) Then I would put the prototypes for the
> private functions into a separate include file also named distinctly,
> e.g. using "-private.h" as suffix.


(I seem to remember that this topic emerged in the near past [0].)

FWIW, I support for both ideas. That is, (1) the "XXXX-private.h" header,
used only when building the library, and not installed with the
development package, and (2) using some consequent name mangling for
pirvate functions that remains inside the "namespace" dedicated to the
library, so that client programmers don't inadvertently trample on the
private-public functions of the library.

Specifically, the public functions seem to start with "dfe_" (a subset --
the group of setup functions -- seems to start with "dfe_ctl_"). I guess
prefixing the currently static functions with "dfe_" and {either suffixing
them with __, or using a prefix like "dfe_prv_" instead} could do the
trick. Also, all types made visible for client programmers should be
renamed to "dfe_XXX" (eg. "sigil_s" -> "dfe_sigil_s").

One exampe happened to poke me in the eye: dfe_connect() -- which has
external linkage -- calls connect(), which currently has internal linkage.
On POSIX(R) / UNIX(R), there already is an extern connect() [1] -- perhaps
irrelevant (for the current form, it certainly is), but it did poke me in
the eye.

BTW, I like the appearance of your code, even though it strongly differs
from my style.

.... Can I have those jelly beans now? :)

Cheers,
lacos

[0] Message-ID: <clcm-20100129-0016@plethora.net>
http://groups.google.com/group/comp....be02b30f8b29df
[1] http://www.opengroup.org/onlinepubs/...s/connect.html

Ersek, Laszlo 06-02-2010 07:25 PM

Re: Splitting a source code file
 
On Wed, 2 Jun 2010, Richard Harter wrote:

> On Wed, 02 Jun 2010 10:22:55 -0700, blp@cs.stanford.edu (Ben
> Pfaff) wrote:
>
>> a __ suffix to denote private functions.) Then I would put the

^^^

> it __connect. Bad news at link time. Now user doesn't want to

^^

I believe you misread "suffix" as "prefix". (I did at first for sure.)

"__connect" is a bad name, no matter the linkage, see C99 7.1.3 "Reserved
identifiers" p1: "[...] All identifiers that begin with an underscore and
either an uppercase letter or another underscore are always reserved for
any use. [...]"

Cheers,
lacos

Ersek, Laszlo 06-02-2010 07:34 PM

Re: Splitting a source code file
 
On Wed, 2 Jun 2010, Ersek, Laszlo wrote:

> I support for both ideas.


Over-editing, sorry. "I support both ideas."

lacos

Ben Pfaff 06-03-2010 03:14 AM

Re: Splitting a source code file
 
cri@tiac.net (Richard Harter) writes:
> Ben Pfaff writes:
>>But that won't happen if
>>you pick a proper prefix for your functions and use it to all of
>>them, even the "private" ones. Suppose your library is libfoo.
>>Public functions might be named foo_<name> and private functions
>>foo_<name>__. There will be no collisions, even for private
>>functions, as long as no other library also uses foo_ as its
>>prefix.

>
> That's the sort of thing that will most likely work and will be a
> real pain if it doesn't. There is no guarantee that all other
> libraries will use that scheme or even that nobody will use foo_
> as a prefix.


If you can't depend on other libraries to pick a reasonable
namespace and stick to it, then you are in trouble no matter what
you do.

You must have some base assumption about what names other
libraries will or won't use. What is it?
--
Ben Pfaff
http://benpfaff.org

Ben Pfaff 06-03-2010 05:00 AM

Re: Splitting a source code file
 
cri@tiac.net (Richard Harter) writes:

> I would put the matter the other way around. Why should I make
> any assumptions about the naming policies of other libraries?


If you don't, then you can only use at most one library, because
you have to assume that every library conflicts with every other
library.
--
Ben Pfaff
http://benpfaff.org

Ben Bacarisse 06-03-2010 04:32 PM

Re: Splitting a source code file
 
cri@tiac.net (Richard Harter) writes:

> On Wed, 02 Jun 2010 22:00:01 -0700, Ben Pfaff
> <blp@cs.stanford.edu> wrote:
>
>>cri@tiac.net (Richard Harter) writes:
>>
>>> I would put the matter the other way around. Why should I make
>>> any assumptions about the naming policies of other libraries?

>>
>>If you don't, then you can only use at most one library, because
>>you have to assume that every library conflicts with every other
>>library.

>
> Cute, Ben, but a bit of a false dichotomy. I grant that at a
> minimum we need at least one unique name for a library. One
> unique name is all we need, if we so choose. If you want to call
> that a naming policy, so be it.


I think the other Ben has more of a point than you grant. Is there, in
a real system, much practical difference between a library with one or
two globally polluting names and one with 50 or 60? You have to make
some sort of assumptions in order to pick one or two names that are
likely to be acceptable, but these choices can almost always be extended
to allow for more names.

I ask out of ignorance. I've always just picked a naming policy and
kept my fingers crossed. Maybe you have experience of situations where
picking one or two "safe" names is easy but extending that to a policy
that is "safe enough" is not.

[Aside: The only way I can see to use one name is to have an array --
either external or pointed to by a function return. Then you'd need to
number the API calls rather than name them and (unless all the functions
happen to have the same type) cast many of the function pointers to the
right type at the point of use. This would be such a mess that in
practise I think you need to have two names: a structure tag and either
a function or an extern reference to an instance of it.]

--
Ben.

Ben Pfaff 06-03-2010 04:42 PM

Re: Splitting a source code file
 
cri@tiac.net (Richard Harter) writes:

> Cute, Ben, but a bit of a false dichotomy. I grant that at a
> minimum we need at least one unique name for a library. One
> unique name is all we need, if we so choose. If you want to call
> that a naming policy, so be it.


This seems so bizarre to me it's hard for me to tell whether you
are serious about it. My system has hundreds of installed
libraries, and none of them, to the best of my knowledge, use the
"one unique name" policy that you appear to advocate. I'm
surprised that, if it's a good idea, it's not in wider use.
--
"What is appropriate for the master is not appropriate for the novice.
You must understand the Tao before transcending structure."
--The Tao of Programming

Ben Pfaff 06-03-2010 04:42 PM

Re: Splitting a source code file
 
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> [Aside: The only way I can see to use one name is to have an array --
> either external or pointed to by a function return. Then you'd need to
> number the API calls rather than name them and (unless all the functions
> happen to have the same type) cast many of the function pointers to the
> right type at the point of use. This would be such a mess that in
> practise I think you need to have two names: a structure tag and either
> a function or an extern reference to an instance of it.]


I think Richard Harter means one name with external linkage, not
one identifier total.
--
"To get the best out of this book, I strongly recommend that you read it."
--Richard Heathfield


All times are GMT. The time now is 01:05 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.