By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,173 Members | 1,079 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,173 IT Pros & Developers. It's quick & easy.

General rules on interface (function) design

P: n/a
Could you talk something about the general rules on the interface
(function) design in C program that recognized publically? Or introduce
some good advice of yourself.

How do you think about some of those advices like following?

a. keep the interface clean and clear (What does clean or clear mean
and how to achieve that?).
b. avoid using static variables in local function if possible.
c. avoid using global variables for local function if possible.
d. avoid allocating dynamic memory in local function if possible.
....

And I write following the function to convert an integer to a string.
Your advices are welcome and appreciated.

Requirement: convert an integer to character string, put one blank char
among the string, for example: "1 2 3 4 0 9" for 123409.

/* s : hold the string presentation of an integer.
* num : an integer is to be gotten its string presentation.
*/
void itoa2(char *s, int num)
{
int len = 100;
char s1[len]; /* C99 features involved */
sprintf(s1, "%d", num);
int i = 0, j = 0;
for (i = 0; s1[i]; ++i, ++j)
{
s[j] = s1[i];
s[++j] = ' ';
}
s[--j] = '\0';
}

How do you think about following choices of different interface design:

/* #2 self-contained or self-sufficient */
void itoa2(char *s, int num);

/* #3 global or static variables or dynamic memory may be required */
void itoa3(int num);
--
lovecreatesbeauty

May 23 '06 #1
Share this Question
Share on Google+
25 Replies


P: n/a
On 23 May 2006 07:19:18 -0700,
lovecreatesbeauty <lo***************@gmail.com> wrote
in Msg. <11**********************@j55g2000cwa.googlegroups .com>
How do you think about some of those advices like following?

a. keep the interface clean and clear (What does clean or clear mean
and how to achieve that?).
b. avoid using static variables in local function if possible.
c. avoid using global variables for local function if possible.
d. avoid allocating dynamic memory in local function if possible.
1. What are "local functions"?

2. If I avoid using global variables "for" local functions, what's
the point of having global variables in the first place?
How do you think about following choices of different interface design:

/* #2 self-contained or self-sufficient */
void itoa2(char *s, int num);

/* #3 global or static variables or dynamic memory may be required */
void itoa3(int num);


Well, "how" do YOU think about them?

#3 certainly has the least cluttered interface; you could unclutter it
even more without hurting functionality or breaking additional coding
standards rules:

void itoa4(void);

robert

PS: Think before you post, and let the success of the thinking reflect
in your posting. But I guess this advice is lost on "Google Groups"
posters.
May 23 '06 #2

P: n/a
lovecreatesbeauty said:
Could you talk something about the general rules on the interface
(function) design in C program that recognized publically? Or introduce
some good advice of yourself.

How do you think about some of those advices like following?

a. keep the interface clean and clear (What does clean or clear mean
and how to achieve that?).
Like many short questions, this one doesn't have a useful short answer. One
or two hints for clean, clear interfaces:

(1) avoid hiding *s in typedefs (some people would say to avoid typedefs
too, but I'm not one of them);
(2) minimise coupling - the dependence of a function on other functions, on
file scope objects, and on "state" generally;
(3) aim for consistency (but not to the point of foolishness) in your
interfaces;
(4) don't publish unnecessary information (for example, maybe your module
uses a binary search tree internally, but probably your users don't need to
know this - telling them is likely to have the effect of making them rely
on the fact, thus perhaps breaking their code when you switch to a hash
table later on).

That list is nothing like exhaustive. I'm afraid that it's far harder to
define the characteristics of a clean, clear interface than it is to
recognise them when you see them!
b. avoid using static variables in local function if possible.
Absolutely. For one thing, a stateless function is easier to grok than a
function containing statics. For another, although C doesn't support
multithreading, many C implementations do - and statics are not
thread-safe.
c. avoid using global variables for local function if possible.
The problems with file scope objects are:

(1) they introduce strong coupling between functions, making it harder to
lift a function out of a program and stick it in a library;
(2) because any function that can see the object can change its value,
debugging is made unnecessarily hard;
(3) shadowing can become a serious problem.

d. avoid allocating dynamic memory in local function if possible.
Why?
And I write following the function to convert an integer to a string.
Your advices are welcome and appreciated.

Requirement: convert an integer to character string, put one blank char
among the string, for example: "1 2 3 4 0 9" for 123409.

/* s : hold the string presentation of an integer.
* num : an integer is to be gotten its string presentation.
*/
void itoa2(char *s, int num)
{
int len = 100;
char s1[len]; /* C99 features involved */
sprintf(s1, "%d", num);
int i = 0, j = 0;
for (i = 0; s1[i]; ++i, ++j)
{
s[j] = s1[i];
s[++j] = ' ';
}
s[--j] = '\0';
}
You can remove the dependence on C99 as follows:

void itoa2(char *s, int num)
{
char s1[(sizeof(int) * CHAR_BIT + 8) / 3] = {0};
char *t = s1;
sprintf(s1, "%d", num);
while(*t != '\0')
{
*s++ = *t++;
*s++ = ' ';
}
*--s = '\0';
}
How do you think about following choices of different interface design:

/* #2 self-contained or self-sufficient */
void itoa2(char *s, int num);
It may be convenient to the user if you were to return a pointer to the null
terminator.
/* #3 global or static variables or dynamic memory may be required */
void itoa3(int num);


No point. It introduces unnecessary complexity.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #3

P: n/a

Richard Heathfield wrote:
<snip>
You can remove the dependence on C99 as follows:

void itoa2(char *s, int num)
{
char s1[(sizeof(int) * CHAR_BIT + 8) / 3] = {0};
char *t = s1;
sprintf(s1, "%d", num);
while(*t != '\0')
{
*s++ = *t++;
*s++ = ' ';
}
*--s = '\0';
}


Thank Richard for the reply.

One more thing is how to do the exception/error check. For example the
availability of the parameter "s" of the function itoa2 doesn't be
validated. How to guarantee the pointer parameters in those aspects (I
also didn't check the pointer parameter in my code snippet):

1. does it refer to a valid memory?
2. is the size of the memory enough for holding the data?

How about the exception handling strategies on other program problems
that much more attention should be paid to?

--
lovecreatesbeauty

May 23 '06 #4

P: n/a
lovecreatesbeauty said:
void itoa2(char *s, int num)

<snip>
One more thing is how to do the exception/error check. For example the
availability of the parameter "s" of the function itoa2 doesn't be
validated.


s is certainly available. Whether it is a valid pointer to sufficient memory
is something which itoa2 cannot ascertain. It must trust the caller.
Therefore, the function's documentation should make it clear that at least
2 * (sizeof(int) * CHAR_BIT + 5) / 3 + 1 bytes should be available via s.

And then it is the caller's responsibility to ensure that this is in fact
the case.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #5

P: n/a


lovecreatesbeauty wrote On 05/23/06 10:19,:
Could you talk something about the general rules on the interface
(function) design in C program that recognized publically? Or introduce
some good advice of yourself.

How do you think about some of those advices like following?

a. keep the interface clean and clear (What does clean or clear mean
and how to achieve that?).
"For motherhood and against sin." (A parodist's summary
of politicians' campaign posturings.)
b. avoid using static variables in local function if possible.
See Richard Heathfield's response. Also, what do you mean
by a "local" function, and how does it differ from "national"
functions or "remote" functions or "express" functions?
c. avoid using global variables for local function if possible.
In addition to the points raised by R.H., note that a file-
scope variable has static storage duration and thus shares the
drawbacks of (b).
d. avoid allocating dynamic memory in local function if possible.
Hogwash. Allocate memory when you need it and as it's
needed. The important thing isn't where it's allocated, but
that it's properly kept track of.
And I write following the function to convert an integer to a string.
Your advices are welcome and appreciated.

Requirement: convert an integer to character string, put one blank char
among the string, for example: "1 2 3 4 0 9" for 123409.

/* s : hold the string presentation of an integer.
* num : an integer is to be gotten its string presentation.
*/
void itoa2(char *s, int num)
{
int len = 100;
char s1[len]; /* C99 features involved */
No need, as shown in R.H.'s post. (However, I see no
reason to initialize the array to all zeroes as he does.)
sprintf(s1, "%d", num);
int i = 0, j = 0;
for (i = 0; s1[i]; ++i, ++j)
{
s[j] = s1[i];
s[++j] = ' ';
}
s[--j] = '\0';
}

How do you think about following choices of different interface design:

/* #2 self-contained or self-sufficient */
void itoa2(char *s, int num);
Unattractive, because it ignores the lesson of gets().
Two alternatives seem plausible:

- Let the caller provide both a buffer pointer and a
buffer size, and the function promises to honor the
size. If the buffer is too small for the number,
the function should be able to return a value that
describes the difficulty. See snprintf().

- In the header that declares itoa2(), #define a macro
named ITOA2BUFSIZE or some such. Require (in the
documentation) that the caller provide at buffer of
at least ITOA2BUFSIZE characters.
/* #3 global or static variables or dynamic memory may be required */
void itoa3(int num);


This signature appears to require a global variable to
communicate the result; I don't like it. The variable might
be the result buffer or a pointer to a dynamically-allocated
buffer or a FILE* stream that the caller can rewind and read
back again ... No matter; I don't like it.

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

May 23 '06 #6

P: n/a
lovecreatesbeauty a écrit :
Richard Heathfield wrote:
<snip>
You can remove the dependence on C99 as follows:

void itoa2(char *s, int num)
{
char s1[(sizeof(int) * CHAR_BIT + 8) / 3] = {0};
char *t = s1;
sprintf(s1, "%d", num);
while(*t != '\0')
{
*s++ = *t++;
*s++ = ' ';
}
*--s = '\0';
}

Thank Richard for the reply.

One more thing is how to do the exception/error check. For example the
availability of the parameter "s" of the function itoa2 doesn't be
validated. How to guarantee the pointer parameters in those aspects (I
also didn't check the pointer parameter in my code snippet):

1. does it refer to a valid memory?
2. is the size of the memory enough for holding the data?

How about the exception handling strategies on other program problems
that much more attention should be paid to?

--
lovecreatesbeauty


That interface is completely screwed up.
You need to pass the length of the buffer s.
You should return a result: true if you converted anything,
false if you did not, at the very least!

Better would be to return the number of characters processed
to the buffer.
May 23 '06 #7

P: n/a
Eric Sosman said:
lovecreatesbeauty wrote On 05/23/06 10:19,:


<snip>

int len = 100;
char s1[len]; /* C99 features involved */


No need, as shown in R.H.'s post. (However, I see no
reason to initialize the array to all zeroes as he does.)


Having been bitten twice by uninitialised objects (in production code), I am
perhaps a little paranoid about this. But I'd rather be paranoid than dead.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #8

P: n/a
Eric Sosman wrote:
- Let the caller provide both a buffer pointer and a
buffer size, and the function promises to honor the
size. If the buffer is too small for the number,
the function should be able to return a value that
describes the difficulty. See snprintf().


Why not simply define the procedure as

void GetIntAsString(char s[], int i);

and let the caller guarantee that s is long enough?
August
May 23 '06 #9

P: n/a
August Karlstrom said:
Eric Sosman wrote:
- Let the caller provide both a buffer pointer and a
buffer size, and the function promises to honor the
size. If the buffer is too small for the number,
the function should be able to return a value that
describes the difficulty. See snprintf().


Why not simply define the procedure as

void GetIntAsString(char s[], int i);

and let the caller guarantee that s is long enough?


Personally, I agree, since the maximum length s needs to be is well-defined.
This is not a gets()-style problem; the function never writes to more than
a trivially calculable number of chars.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #10

P: n/a


August Karlstrom wrote On 05/23/06 13:07,:
Eric Sosman wrote:
- Let the caller provide both a buffer pointer and a
buffer size, and the function promises to honor the
size. If the buffer is too small for the number,
the function should be able to return a value that
describes the difficulty. See snprintf().

Why not simply define the procedure as

void GetIntAsString(char s[], int i);

and let the caller guarantee that s is long enough?


That's pretty close to my second suggestion, which was
to "publish" the maximum number of characters the function
might use. That number can be derived from the values in
<limits.h>, so the caller could perfectly well calculate it
for himself, but I think it would be "friendlier" to provide
the value in an easy-to-use form.

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

May 23 '06 #11

P: n/a
Richard Heathfield <in*****@invalid.invalid> writes:
August Karlstrom said:
Eric Sosman wrote:
- Let the caller provide both a buffer pointer and a
buffer size, and the function promises to honor the
size. If the buffer is too small for the number,
the function should be able to return a value that
describes the difficulty. See snprintf().


Why not simply define the procedure as

void GetIntAsString(char s[], int i);

and let the caller guarantee that s is long enough?


Personally, I agree, since the maximum length s needs to be is well-defined.
This is not a gets()-style problem; the function never writes to more than
a trivially calculable number of chars.


It's trivally calculable, but it's also trivially miscalculable.

For example, someone using this function might assume that an int
won't be bigger than 32 bits, so the program will fail when ported to
a system with 64-bit ints -- or the caller might forget to leave room
for the sign.

One approach is to require the user to specify, in another argument,
the actual size of the string; this would at least allow the function
to detect a user error.

The maximum length needed for an int is fairly easy to calculate, and
a case can be made that getting it wrong is the caller's fault. But
if this is one of a set of similar functions for various types, you'll
probably want something like this anyway (how many characters to you
need to provide for a long double, or a pointer?).

On the other hand, that does make the interface more complex.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
May 23 '06 #12

P: n/a
"Richard Heathfield" <in*****@invalid.invalid> wrote
d. avoid allocating dynamic memory in local function if possible.


Why?

One problem is that the allocation can always fail.
maybe you are allocating a trivial number of bytes to hold a filename, on a
system which needs a gigabyte of memory to runyour program. The chance of
the computer running out of memory may be less than the chance of it
breaking, but you still have to pass up an error return to be formally
correct. then the caller has to handle it somehow.

Another problem is that you might want to port to a system that doesn't have
dynamic memory.

These considerations were why strdup() wasn't included in the standard
library.
--
Buy my book 12 Common Atheist Arguments (refuted)
$1.25 download or $7.20 paper, available www.lulu.com/bgy1mm
May 23 '06 #13

P: n/a


Malcolm wrote On 05/23/06 15:22,:
"Richard Heathfield" <in*****@invalid.invalid> wrote
d. avoid allocating dynamic memory in local function if possible.
Why?


One problem is that the allocation can always fail.
maybe you are allocating a trivial number of bytes to hold a filename, on a
system which needs a gigabyte of memory to runyour program. The chance of
the computer running out of memory may be less than the chance of it
breaking, but you still have to pass up an error return to be formally
correct. then the caller has to handle it somehow.


This is an argument for avoiding *any* operation that
might fail: No fopen(), no time(), no getenv(), no ...
One wonders what would remain.
Another problem is that you might want to port to a system that doesn't have
dynamic memory.
The requirements of free-standing systems are special.
Again, though, this argues against calling printf(), sqrt(),
longjmp(), strlen(), exit(), ...
These considerations were why strdup() wasn't included in the standard
library.


Are you sure this was the reason? I can find nothing
about the matter in the Rationale; what did I overlook?

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

May 23 '06 #14

P: n/a
Malcolm wrote:
"Richard Heathfield" <in*****@invalid.invalid> wrote
d. avoid allocating dynamic memory in local function if possible.
Why?

One problem is that the allocation can always fail.
maybe you are allocating a trivial number of bytes to hold a filename, on a
system which needs a gigabyte of memory to runyour program. The chance of
the computer running out of memory may be less than the chance of it
breaking, but you still have to pass up an error return to be formally
correct. then the caller has to handle it somehow.


I suppose, the so called "rules" for function interfaces are not cast
in stone and will vary according to the target environment and the
programmer's/client's aims and requirements.

Maybe dynamic memory allocation is rather more costly/risky in
low-resource enviroments like the embedded work, but if it is advised
against under general PC/Mainframe area, then not much can be
accomplished in C.

Further static memory allocation has it's own problems like
inflexibility, and propensity for buffer overflows.
Another problem is that you might want to port to a system that doesn't have
dynamic memory.


Yes, but if general "rules" like these should be provided at all, I
would think that they would tend to target the "common" case. I may be
wrong here, but it seems to me that systems incapable of dynamic memory
allocations would not be the "common" case.

May 23 '06 #15

P: n/a
"santosh" <sa*********@gmail.com> wrote
Another problem is that you might want to port to a system that doesn't
have
dynamic memory.


Yes, but if general "rules" like these should be provided at all, I
would think that they would tend to target the "common" case. I may be
wrong here, but it seems to me that systems incapable of dynamic memory
allocations would not be the "common" case.

It's more common than you might imagine not to have dynamic memory.
If you write only for PCs and UNIX boxes then of course you don't need to
worry, but a lot of C doesn't run under those operating systems.
--
Buy my book 12 Common Atheist Arguments (refuted)
$1.25 download or $7.20 paper, available www.lulu.com/bgy1mm
May 23 '06 #16

P: n/a
Malcolm said:
"Richard Heathfield" <in*****@invalid.invalid> wrote
d. avoid allocating dynamic memory in local function if possible.
Why?

One problem is that the allocation can always fail.


Is this the same Malcolm we know and love? :-)

It's certainly true that the allocation can fail, yes. The possibility of
failure should not stop us from reaping the rewards of success. It does
mean, however, that we should anticipate the failure and handle it as
gracefully as possible.

<snip>
Another problem is that you might want to port to a system that doesn't
have dynamic memory.

These considerations were why strdup() wasn't included in the standard
library.


ISTR that the actual reason was that they couldn't make up their minds
whether the prototype belonged in stdlib.h or string.h :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #17

P: n/a
Robert Latest wrote:
On 23 May 2006 07:19:18 -0700,
1. What are "local functions"?
I am sorry to use a wrong word, please ignore it. English is not my
mother language, but Chinese is. I am not a excellent C programmer, so
come to learn from you all. Thank you.
PS: Think before you post, and let the success of the thinking reflect
in your posting.
I agree with you. One problem to me is that I can not use a good
English, so sorry. I'm improving the expressing skills in language.
But I guess this advice is lost on "Google Groups"
posters.


I think it is not important whether one use Google groups or some news
reader.

Thanks for so much good advice and great help from you all.

--
lovecreatesbeauty

May 24 '06 #18

P: n/a
Richard Heathfield wrote:
s is certainly available. Whether it is a valid pointer to sufficient memory
is something which itoa2 cannot ascertain. It must trust the caller.
Therefore, the function's documentation should make it clear that at least
2 * (sizeof(int) * CHAR_BIT + 5) / 3 + 1 bytes should be available via s.

And then it is the caller's responsibility to ensure that this is in fact
the case.


But I saw some programmers (in some programs or even in some C books)
checked if the parameter s is NULL, though the memory size pointed by
the parameter s can not be detected. Or even assert() was used to
check/guarantee the pointer parameter availability at these occassion.

void itoa2(char *s, int num)
{

/* ... */

/* assert(s); */

if (s == NULL)
{
return; /* invalid parameters */
}

/* ... */
}

May 24 '06 #19

P: n/a
lovecreatesbeauty said:
Richard Heathfield wrote:
s is certainly available. Whether it is a valid pointer to sufficient
memory is something which itoa2 cannot ascertain. It must trust the
caller. Therefore, the function's documentation should make it clear that
at least 2 * (sizeof(int) * CHAR_BIT + 5) / 3 + 1 bytes should be
available via s.

And then it is the caller's responsibility to ensure that this is in fact
the case.
But I saw some programmers (in some programs or even in some C books)
checked if the parameter s is NULL,


Sorry, I should have mentioned NULL. Yes, if s is NULL then it's definitely
invalid. But if s is /not/ NULL, then it might be valid and it might not,
and you can't tell just by looking at it.

though the memory size pointed by
the parameter s can not be detected.
Right.
Or even assert() was used to
check/guarantee the pointer parameter availability at these occassion.

void itoa2(char *s, int num)
{

/* ... */

/* assert(s); */


If you're going to use assert to check a pointer against NULL (which is
sometimes a good idea and sometimes not), check it against NULL!

assert(s != NULL);

In C99, assert(s) is fine, because they changed the rules, but almost nobody
has a conforming C99 compiler, so you're better off with an integer
expression than a pointer expression. (Under C90, only the integer
expression is guaranteed to work; under C99, either form will do. So the
integer expression is more portable.)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 24 '06 #20

P: n/a
On Tue, 23 May 2006 16:00:27 -0400,
Eric Sosman <Er*********@sun.com> wrote
in Msg. <1148414431.797794@news1nwk>
These considerations were why strdup() wasn't included in the standard
library.


Are you sure this was the reason? I can find nothing
about the matter in the Rationale; what did I overlook?


I've thought about this, too; my personal explanation so far is that the
committee wanted to keep the memory handling interface small and clean.
I don't think there are any functions besides malloc(), calloc() and
realloc() that return dynamically allocated memory which IMO is a good
idea.

Maybe I'm wrong though. I'd appreciate comments.

robert
May 24 '06 #21

P: n/a
Robert Latest wrote:
On Tue, 23 May 2006 16:00:27 -0400,
Eric Sosman <Er*********@sun.com> wrote
in Msg. <1148414431.797794@news1nwk>
These considerations were why strdup() wasn't included in the standard
library.


Are you sure this was the reason? I can find nothing
about the matter in the Rationale; what did I overlook?

I've thought about this, too; my personal explanation so far is that the
committee wanted to keep the memory handling interface small and clean.
I don't think there are any functions besides malloc(), calloc() and
realloc() that return dynamically allocated memory which IMO is a good
idea.

Maybe I'm wrong though. I'd appreciate comments.


These are the only Standard library functions that are
"advertised" to return dynamically allocated memory, hence
the only functions for which the burden of managing the
memory's lifetime falls on the caller, the only functions
whose returned value is safe to pass to free().

However, other library functions "may" return pointers
to dynamically allocated memory. fopen(), for example, returns
a FILE*, a pointer to a FILE. Might the FILE be dynamically
allocated? Certainly it might, and fclose() presumably takes
care of deallocating it.

As I wrote elsewhere in this thread, the important issue
isn't whether memory is dynamically allocated, but that the
allocation is properly managed. When a function allocates
memory, it must be clear who is responsible for managing it
afterwards. malloc() and calloc() and realloc() are the only
Standard library functions that place the entire burden on
their callers, but other functions (like the hypothetical
fopen() above) may make other arrangements.

The original suggestion in this thread was that "local"
functions should not as a rule allocate dynamic memory. I'm
still unsure what "local" is supposed to mean, but does anyone
think it a bad idea for fopen() to call malloc()?

--
Eric Sosman
es*****@acm-dot-org.invalid
May 24 '06 #22

P: n/a
Eric Sosman wrote:
but does anyone
think it a bad idea for fopen() to call malloc()?


I don't think it breaks anything
if fopen does call malloc,
with the implication you described,
that fclose will behave suitably.

--
pete
May 24 '06 #23

P: n/a
On Wed, 24 May 2006 08:53:11 -0400,
Eric Sosman <es*****@acm-dot-org.invalid> wrote
in Msg. <RI********************@comcast.com>
The original suggestion in this thread was that "local"
functions should not as a rule allocate dynamic memory. I'm
still unsure what "local" is supposed to mean, but does anyone
think it a bad idea for fopen() to call malloc()?


No. In fact, it probably does on my implementation (a Linux system).
From the fopen(3) manpage:

The fopen, fdopen and freopen functions may also fail and set
errno for any of the errors specified for the routine malloc(3).

There you go.

robert
May 24 '06 #24

P: n/a
Eric Sosman wrote:
.... snip ...
The original suggestion in this thread was that "local"
functions should not as a rule allocate dynamic memory. I'm
still unsure what "local" is supposed to mean, but does anyone
think it a bad idea for fopen() to call malloc()?


I certainly hope not. I suspect the OP considers statid functions
to be 'local' functions. At any rate I see no problem with such
animals calling malloc and friends, as long as they are clearly
documented as requiring an eventual free, or corresponding release
call. The latter may be necessary for things that have internal
levels, such as structures with pointers to strings.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
May 24 '06 #25

P: n/a
CBFalconer wrote:
I suspect the OP considers statid functions
to be 'local' functions.


Is statid a misspelling of "static"?

I used the word "local" wrongly in the original post. I am sorry to
bring the confusion. Please ignore it.

A function has file scope. When function name is qualified with
"static", the function is visible only within the file. I think this is
the only one difference between a static function and non-static one.
So, some general rules on function interface design can be applied to
static function as same as non-static one.

--
lovecreatesbeauty

May 25 '06 #26

This discussion thread is closed

Replies have been disabled for this discussion.