473,421 Members | 1,631 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,421 software developers and data experts.

Making function private/ not supplying declaration in header file

I've noticed that in a C module (.c, .h file combination) that if you
create a function's definition before it is used in other functions
than a declaration is not necessary. I believe if the compiler can
find the definition of the function prior to encountering the use of
the function it will generate the prototype itself.

I don't currently use this feature, I explicitly create declarations
for all functions in a header file. However, I do think this feature
would be jolly useful for functions which can be thought of as private
to the module and nobody else ever needs to use. As well as not
actually appearing in the header file, so nobody will try to use it,
if the signature for this function is changed no changes are necessary
to the header file and we therefore remove a whole set of dependencies
when we re-compile.

Is the consensus that this is a good compiler side-effect to use or is
it best avoided, to become de-supported, already not supported by C++,
etc.

Thanks,
Daniel.

Nov 14 '05 #1
6 7948
Thanks everybody for feedback.

I'm familiar with the "Pascal style" of function layout in files as I
do a lot of Oracle PL/SQL programming which is based a little on ADA
and Pascal. This is why I first tried the idea of missing the
prototype out of the header. I would never put a function in a PL/SQL
specification file if it was private but do so all the time in C.

I can easily create static prototypes in my .c files for these
private/internal functions. It will certainly help minimise
re-compiles when these "internal" functions change their prototypes.

However, I'm still wondering if it is easier to maintain the C file if
you don't duplicate the prototype: once before use (at the top of the
..c file) and then again since the function is defined before it's
first use (as "Default User" points out.)

It's just Eric Sosman states it is good practice to declare a function
before use. Is it because, if you do prototype explicitly you can
position the function physically anywhere in the file?

Obviously, things work as they are but I don't want to have to go and
duplicate prototypes up at some later time after a code review from
someone who thinks prototypes are essential and required for C99.

Nov 14 '05 #2
Daniel Nichols wrote:
Thanks everybody for feedback.
[...]
It's just Eric Sosman states it is good practice to declare a function
before use. Is it because, if you do prototype explicitly you can
position the function physically anywhere in the file?
Under C99 rules, every function must be declared before
the first reference to it. Under C89, a preceding declaration
can be omitted if the function returns `int' and has an argument
list compatible with the K&R form; all other functions must be
declared before use, even in C89.

There are a couple of reasons why it's "good practice" to
declare before use even when C89 would let you get away without
it. First, there's the likelihood that you will someday want
to move the code to a C99 environment, where the declaration
becomes mandatory. Second, no "variadic" function has a K&R-
compatible argument list (the `...' can't be expressed in K&R),
so it follows that every variadic function must be pre-declared.
Third, it's surprisingly difficult to determine whether a given
function has a K&R-compatible argument list! For example,

int a(size_t x) { ... }
int b(time_t x) { ... }
int c(char x) { ... }
int d(enum foo x) { ... }

may be K&R-compatible on some implementations but not on others.

"Good practice" quite often amounts to little more than
avoiding unpleasant surprises.

The advantage of writing pure declarations (the above, but
replacing each `{ ... }' with `;') is that if you stick 'em all
somewhere near the top of the file you can then arrange the
actual function definitions in whatever order makes it easiest
for you to read. The disadvantage, as you noted in some text I
snipped, is that when you write both a declaration and a definition
you are repeating yourself and thus have the opportunity to
contradict yourself -- the compiler will complain about the
contradiction, but it's an error that simply can't arise if you use
the "Pascal style."

And, of course, there are some situations where declarations
are unavoidable. Mutually recursive functions, for example:

double a(void) {
...
x = b();
}

double b(void) {
...
y = a();
}

.... cannot be made to work without introducing a declaration
of b() separate from its definition.
Obviously, things work as they are but I don't want to have to go and
duplicate prototypes up at some later time after a code review from
someone who thinks prototypes are essential and required for C99.


You're still confusing "declaration" and "prototype."
Function declarations (remember, a definition is also a
declaration) are sometimes required and sometimes optional
in C89, are always required in C99, and are always good
practice under either Standard. Argument-list prototypes
are mandatory for variadic (`...') functions and for functions
that accept "narrow" argument types (`float' and usually some
others), optional for fixed-list functions with "wide"
arguments, and good practice always, under both Standards.

Here are two function definitions (and declarations),
one with a prototype and one without:

double f(int a, float b, char *c)
{ ... }

double g(a, b, c)
int a;
float b;
char *c;
{ ... }

Here are correct declarations of these functions, using
prototypes:

double f(int, float, char*);
double g(int, double, char*);

Note the declared type of the second argument to g(). It's
hard in general to get this right, and that's one reason
not to mix'n'match ANSI prototypes with K&R functions.

Here is a correct declaration of g(), with no prototype:

double g();

It is not possible to declare f() correctly without using
a prototype -- which is a reason not to mix'n'match ANSI
function definitions with K&R prototypeless declarations.

--
Er*********@sun.com

Nov 14 '05 #3
Thanks for your detailed explanation. It's now clear what to do.

Nov 14 '05 #4
Daniel Nichols wrote:

I'm familiar with the "Pascal style" of function layout in files
as I do a lot of Oracle PL/SQL programming which is based a
little on ADA and Pascal. This is why I first tried the idea of
missing the prototype out of the header. I would never put a
function in a PL/SQL specification file if it was private but do
so all the time in C.


The so-called Pascal style is just fine. A complete function
definition constitutes a valid prototype, and as long as it
precedes use no separate prototype is ever required. In fact it
should be avoided, because it just one more place to make a
copying mistake.

There are two fundamental reasons for prototypes. 1. To allow
mutual recursion. 2. To allow construction of header files,
which in turn are used to publish the interface to a compilation
unit.

A third, not necessary, reason is to remove the need for ordering
in the source file. I consider this a hindrance, since without it
I know the source for a routine (or a prototype) will be found by
looking towards the beginning. (You can get the same effect in
Pascal source by declaring all functions/procedures as "forward" -
very ugly)

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #5
On Mon, 14 Jun 2004 20:36:15 GMT, CBFalconer <cb********@yahoo.com>
wrote in comp.lang.c:
Daniel Nichols wrote:

I'm familiar with the "Pascal style" of function layout in files
as I do a lot of Oracle PL/SQL programming which is based a
little on ADA and Pascal. This is why I first tried the idea of
missing the prototype out of the header. I would never put a
function in a PL/SQL specification file if it was private but do
so all the time in C.
The so-called Pascal style is just fine. A complete function
definition constitutes a valid prototype, and as long as it


No, a complete function definition necessarily constitutes a
declaration. It may or may not also provide a prototype.

int func(x, y)
int x, y;
{
return x + y;
}

....provides a declaration of func() as a function accepting an
unspecified, but fixed, set of arguments, but it is not a prototype.
This is all the declaration that is needed for non-variadic functions
even in C99.
precedes use no separate prototype is ever required. In fact it
should be avoided, because it just one more place to make a
copying mistake.

There are two fundamental reasons for prototypes. 1. To allow
mutual recursion. 2. To allow construction of header files,
which in turn are used to publish the interface to a compilation
unit.

A third, not necessary, reason is to remove the need for ordering
in the source file. I consider this a hindrance, since without it
I know the source for a routine (or a prototype) will be found by
looking towards the beginning. (You can get the same effect in
Pascal source by declaring all functions/procedures as "forward" -
very ugly)


Some coding standards, including MISRA C, require that a prototype be
in scope not only at the call, but also at the definition of all
functions, and that includes static ones.

PCLint will diagnose a failure to meet this requirement if its MISRA C
rule set is used, even for static functions.

There is at least one C compiler (CodeWarrior) that has an option to
emit a warning message if this is violated, even for static functions.

The tools above will also emit a warning for any function with
external linkage (except for main()) defined without a prototype in
scope.

I personally insist on this requirement in the coding requirements for
all projects that I participate in. Otherwise larger projects with
multiple programmers would quickly descend into chaos.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #6
Jack Klein wrote:
CBFalconer <cb********@yahoo.com> wrote in comp.lang.c:

.... snip ...

The so-called Pascal style is just fine. A complete function
definition constitutes a valid prototype, and as long as it


No, a complete function definition necessarily constitutes a
declaration. It may or may not also provide a prototype.

int func(x, y)
int x, y;
{
return x + y;
}

...provides a declaration of func() as a function accepting an
unspecified, but fixed, set of arguments, but it is not a
prototype. This is all the declaration that is needed for
non-variadic functions even in C99.


I always forget that, because I never use old fashioned function
definitions. They were the prime insecurity reason I refused to
use C in the old days.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Penn Markham | last post by:
Hello all, I am writing a script where I need to use the system() function to call htpasswd. I can do this just fine on the command line...works great (see attached file, test.php). When my...
0
by: |-|erc | last post by:
Hi! Small challenge for you. The index.php uses this file and calls layout(). Take a look at www.chatty.net this file draws the chat login box on the right. I traced the CHAT button it submits...
16
by: Vu Pham | last post by:
I think this problem relates to either c or c++ ( but I am not sure which one ) so I post to both of these news group. I am sorry if I did something wrong here. Is there any difference between...
12
by: Bryan Parkoff | last post by:
CMain Class is the base class that is initialized in main function. CA Class is the base class that is initialized in CMain::CMain(). CMain Class is always public while CA Class is always...
5
by: Daniel Nichols | last post by:
I've noticed that in a C module (.c, .h file combination) that if you create a function's definition before it is used in other functions than a declaration is not necessary. I believe if the...
3
by: AK | last post by:
I'm using a .NET Windows Forms Applications project. I'm using LoadLibrary & GetProcAddress to use a DLL function. This is all done in the main cpp file. I would like to use this DLL function in a...
1
by: yancheng.cheok | last post by:
currently, i have a private function in cat named privateFun. i would like to have this function "private" to all except dog's action member function. by using the following approach, all the...
3
by: sam_cit | last post by:
Hi Everyone, I have seen in some project where functions are declared as extern, what is the possible reason to do this? To my best understanding, if some other file wan't to invoke this...
50
by: Juha Nieminen | last post by:
I asked a long time ago in this group how to make a smart pointer which works with incomplete types. I got this answer (only relevant parts included): ...
28
by: Why Tea | last post by:
I seem to remember that in ANSI C, all static functions should have their function prototypes listed at the beginning of the file for better consistency (or something like that). I googled and...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.