KR1 Still up-to-date?

  • Thread starter J. (Hans) D. Lodder
  • Start date
J

J. (Hans) D. Lodder

Hi!

Recently I have been re-reading my KR1 book to refresh my C knowledge
(yes indeed, quite rusty!).

Regarding this I have a couple of questions. I a busy writing a C
program, which I want to be relatively robust.

1. Memory allocation and freeing

Are alloc() and free() still the safest options?

2. Read 1 line of input

Is getline() still the safest option?

3. Printing error messages and aborting

Is my best option fprintf (stderr, "msg") and exit (1)?

It is not only an answer I am looking for, but also why, including
possible examples and references.

Can you help me?

Kind regards,

Hans Lodder
 
S

Seebs

Regarding this I have a couple of questions. I a busy writing a C
program, which I want to be relatively robust.

You need a newer book.

Perhaps most importantly, K&R 1 will be showing you an obsolete form of
function declaration and usage which is intrinsically unsafe.
1. Memory allocation and freeing
Are alloc() and free() still the safest options?

There is no alloc(). There are malloc() and free(), but I don't know
what you mean by "safe".
2. Read 1 line of input
Is getline() still the safest option?

It never was, but it's become even less so from a portability standpoint
as at least one major C library provides its own incompatible variant.
3. Printing error messages and aborting
Is my best option fprintf (stderr, "msg") and exit (1)?

Probably not.
It is not only an answer I am looking for, but also why, including
possible examples and references.

These are large complicated questions, but most importantly, you don't
even know the questions you should be asking. Things like:

Do modern C compilers still use the same kinds of function
declarations and definitions that are shown in K&R 1?

No, no they do not.
Can you help me?

Not much, except to recommend King's _C Programming: A Modern Approach_
if you want to relearn modern C.

-s
 
B

Barry Schwarz

Hi!

Recently I have been re-reading my KR1 book to refresh my C knowledge
(yes indeed, quite rusty!).

Regarding this I have a couple of questions. I a busy writing a C
program, which I want to be relatively robust.

What does robust mean to you? Is portable part of the definition?
1. Memory allocation and freeing

Are alloc() and free() still the safest options?

What does safe mean to you? Are you concerned abut 3rd party
libraries?

alloc() is not a standard C function. There is malloc. malloc (and
its two cousins) and free are the only standard options. (There may
be other options if you will always run on a POSIX system.)
2. Read 1 line of input

Is getline() still the safest option?

getline is not a standard function. Not having one on my system, I
would expect fgets is the closest standard function. (See previous
POSIX comment.)
3. Printing error messages and aborting

Is my best option fprintf (stderr, "msg") and exit (1)?

Your fprintf approach uses only standard features but
fprintf(stderr, "%s", "msg");
eliminates problems caused if msg contains '%'.

1 is not a portable value to pass to exit. EXIT_FAILURE is the
portable value.

Depending on your program, the abort function may serve you better.
It is not only an answer I am looking for, but also why, including
possible examples and references.

Download the free n1256 draft of the C99 standard. Your reference is
over 20 years out of date.
 
K

Keith Thompson

Seebs said:
These are large complicated questions, but most importantly, you don't
even know the questions you should be asking. Things like:

Do modern C compilers still use the same kinds of function
declarations and definitions that are shown in K&R 1?

No, no they do not.

Yes, yes they do.

Old-style function declarations are still legal, even in C99, and
conforming compilers still support them -- but only for backward
compatibility.

That's not to say that programmers should use them. No, no they
should not.
 
K

Keith Thompson

J. (Hans) D. Lodder said:
Recently I have been re-reading my KR1 book to refresh my C knowledge
(yes indeed, quite rusty!).

K&R1 was published in 1978. It's a classic, but it describes an
obsolete version of the language. Get a copy of the second edition.
Regarding this I have a couple of questions. I a busy writing a C
program, which I want to be relatively robust.

1. Memory allocation and freeing

Are alloc() and free() still the safest options?

malloc() and free() are the standard memory allocation and deallocation
functions.
2. Read 1 line of input

Is getline() still the safest option?

There is no getline() function in the C standard. (gets() is
standard, but inherently unsafe; don't use it.)
3. Printing error messages and aborting

Is my best option fprintf (stderr, "msg") and exit (1)?

exit(1) should be exit(EXIT_FAILURE), unless you have a specific
(system-dependent) requirement to use 1.

[...]
 
L

Lew Pitcher

J. (Hans) D. Lodder said:
Recently I have been re-reading my KR1 book to refresh my C knowledge
(yes indeed, quite rusty!). [snip]
2. Read 1 line of input

Is getline() still the safest option?

There is no getline() function in the C standard. (gets() is
standard, but inherently unsafe; don't use it.)

However, K&R provides /two/ versions of getline(), in source form (one on
p26 and one on p67), both of which appear to be a bit safer than gets().
 
N

Nobody

Your fprintf approach uses only standard features but
fprintf(stderr, "%s", "msg");
eliminates problems caused if msg contains '%'.

That could be misinterpreted.

The format argument (the first argument to printf and the second argument
to fprintf and sprintf) should normally be a string literal. Or at least
an expression which reduces to a string literal, e.g.:

fprintf(stderr, result ? "success\n" : "failure\n");

At the very least, it must be not be an arbitrary string which might
contain the '%' character.

If you want to print a literal string which happens to contain a '%'
character, double it:

fprintf(stderr, "100%% complete\n");

Or use fputs():

fputs("100% complete\n", stderr);

[For some reason, people seem to be allergic to using fputs().]

If you want to print an unknown string which could contain '%' characters,
use "%s" as the format string and pass the unknown string as an argument:

fprintf(stderr, "%s", message);

Or use fputs():

fputs(message, stderr);
 
S

Seebs

Yes, yes they do.
Old-style function declarations are still legal, even in C99, and
conforming compilers still support them -- but only for backward
compatibility.
That's not to say that programmers should use them. No, no they
should not.

I guess, my question would be:

Does <stdio.h> include the line "int printf();"?

If not, then the compiler isn't using K&R-style function declarations
anymore. Supporting something for backwards compatibility, even though
it's been obsolete for twenty years, isn't the same as using it.

-s
 
O

osmium

Seebs said:
I guess, my question would be:

Does <stdio.h> include the line "int printf();"?

If not, then the compiler isn't using K&R-style function declarations
anymore. Supporting something for backwards compatibility, even though
it's been obsolete for twenty years, isn't the same as using it.

To the OP, if he is still here. The debate is about the difference between
"using" and "allowing" in the English language.
 
R

Ralf Damaschke

Seebs said:
I guess, my question would be:

Does <stdio.h> include the line "int printf();"?

If not, then the compiler isn't using K&R-style function declarations
anymore.

Are you sure? IIRC, the presence or absence of this declaration would
not have changed anything in these old days.

-- Ralf
 
S

Seebs

Are you sure? IIRC, the presence or absence of this declaration would
not have changed anything in these old days.

Although I think you're right that it might not change anything, in
practice I seem to recall headers declaring stuff anyway on principle,
since lint and other tools could warn about implicit declarations anyway.

-s
 
B

Barry Schwarz

That could be misinterpreted.

The format argument (the first argument to printf and the second argument
to fprintf and sprintf) should normally be a string literal. Or at least
an expression which reduces to a string literal, e.g.:

You eliminate the possibility of generating the format string on the
fly. Why?
fprintf(stderr, result ? "success\n" : "failure\n");

At the very least, it must be not be an arbitrary string which might
contain the '%' character.

If you want to print a literal string which happens to contain a '%'
character, double it:

fprintf(stderr, "100%% complete\n");

Or use fputs():

fputs("100% complete\n", stderr);

[For some reason, people seem to be allergic to using fputs().]

If you want to print an unknown string which could contain '%' characters,
use "%s" as the format string and pass the unknown string as an argument:

fprintf(stderr, "%s", message);

Or use fputs():

fputs(message, stderr);
 
P

Peter Nilsson

Seebs said:
I guess, my question would be:

Does <stdio.h> include the line "int printf();"?

Unlikely, since this is not the equivalent declaration of
the variadic function printf. [Although it may be on given
implementations.] Perhaps a better example is int puts().

I note that C99 explicitly requires all functions declared in
headers to be prototyped. My C89 draft does not have that
requirement.
 
U

Uno

J. (Hans) D. Lodder said:
Recently I have been re-reading my KR1 book to refresh my C knowledge
(yes indeed, quite rusty!). [snip]
2. Read 1 line of input

Is getline() still the safest option?

There is no getline() function in the C standard. (gets() is
standard, but inherently unsafe; don't use it.)

However, K&R provides /two/ versions of getline(), in source form (one on
p26 and one on p67), both of which appear to be a bit safer than gets().

I basically got taken on a book purchase and ended up with H&S 1 instead
of H&S V. The experience was terrible. I hated the book. Through it out.

I get a little money, buy H&S V, and now I've lost it. :(
 
J

J. (Hans) D. Lodder

Recently I have been re-reading my KR1 book to refresh my C knowledge
(yes indeed, quite rusty!).

Regarding this I have a couple of questions. I a busy writing a C
program, which I want to be relatively robust.

I meant here with robustness what we used to call 'defensive
programming'. Doing anything you can to prevent that on one day a small
change has (difficult predictable) large side effects, or that adding
valuable functionality causes a complete rewrite, which should not have
been necessary.

1. Memory allocation and freeing

Are alloc() and free() still the safest options?

malloc and free.

2. Read 1 line of input

Is getline() still the safest option?

fgets, because it is a C standard function.

3. Printing error messages and aborting

Is my best option fprintf (stderr, "msg") and exit (1)?

fprintf(stderr, "%s", msg) and abort().
 
K

Keith Thompson

One piece of advice missing from your summary is that you should get a
copy of K&R2 (or perhaps some other modern C book).

[...]
fprintf(stderr, "%s", msg) and abort().

No, the replacement for exit(1) is exit(EXIT_FAILURE). abort()
causes *abnormal* program termination, by raising the SIGABRT signal,
whereas exit(EXIT_FAILURE) merely causes the program to terminate
with an indication that it failed.
 
N

Nobody

You eliminate the possibility of generating the format string on the
fly. Why?

Well, I did say "normally". Originally I was just going to stop after
"string literal", but a choice of string literals is safe enough.

Dynamically generated format strings ... I've never found a use for
this. The fact that the argument list is fixed limits what you
could actually do with this.
 
B

Ben Pfaff

Nobody said:
Dynamically generated format strings ... I've never found a use for
this. The fact that the argument list is fixed limits what you
could actually do with this.

They are commonly used for internationalization. The format
string is passed to a function that (possibly) translates it into
another language.
 
S

Seebs

Dynamically generated format strings ... I've never found a use for
this. The fact that the argument list is fixed limits what you
could actually do with this.

Limits, yes, but does not eliminate. The obvious case is stuff like
localization. Historically, you used to see a fair bit of code
to the effect of:
sprintf(fmt, "%%%ds", len);
but this is mostly gone because '*' can now be used as a width or
precision. (I'm not sure whether '*' didn't exist back then, or people
were just less likely to know about it, or what.)

-s
 

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,954
Messages
2,570,114
Members
46,702
Latest member
VernitaGow

Latest Threads

Top