Tuesday, December 18, 2007

C Interview Questions - Part 6

11.5: Why does the declaration
extern int f(struct x *p);
give me an obscure warning message about "struct x introduced in
prototype scope"?
---
give me an obscure warning message about "struct x declared
inside parameter list"?
==========
A: "const char *p" (which can also be written "char const *p")
declares a pointer to a constant character (you can't change
the character); "char * const p" declares a constant pointer
---
any pointed-to characters); "char * const p" declares a constant
pointer to a (variable) character (i.e. you can't change the
pointer).
==========
A: The problem is older linkers which are under the control of
---
A: The problem is linkers which are under control of
neither the ANSI/ISO Standard nor the C compiler developers
on the systems which have them.
==========
If you're interested in writing portable code, you can ignore
the distinctions, as you'll want to avoid code that depends
---
the distinctions, as you'll usually want to avoid code that
depends on any of the three behaviors.
==========
A: The functions in locale.h begin to provide some support for
these operations, but there is no standard routine for doing
---
these operations, but there is no standard function for doing
either task.
==========
If you're worried about using floating point, you could use
---
If you'd rather not use floating point, another method is
rand() / (RAND_MAX / N + 1)
==========
A: In general, a header file contains only declarations.
---
A: In general, a header file contains only external declarations.
==========
how carefully your compiler's binary/decimal conversion routines
(such as those used by printf) have been written, you may see
discrepancies when numbers (especially low-precision floats) not
exactly representable in base 2 are assigned or read in and then
---
discrepancies when numbers not exactly representable in base 2
are assigned or read in and then printed (i.e. converted from
base 10 to base 2 and back again).
==========
Another possibility is to to format the value in question using
---
Another possibility is to format the value in question using
sprintf(): on many systems it generates strings like "NaN"
==========
A: Some compilers for small machines, including Borland's
---
A: Some compilers for small machines, including Turbo C
Ritchie's original PDP-11 compiler), leave out certain floating
==========
char *vstrcat(char *first, ...)
---
char *vstrcat(const char *first, ...)
==========
void error(char *fmt, ...)
---
void error(const char *fmt, ...)
==========
examples in questions 5.2 and 15.4). Finally, if their types
---
examples in questions 5.2 and 15.4). Finally, if the types
are predictable, you can pass an explicit count of the number of
==========
local arrays. Many systems have fixed-size stacks, and
---
local arrays. Many systems have fixed-size stacks, and even
those which perform dynamic stack allocation automatically
(e.g. Unix) can be confused when the stack tries to grow by a
huge chunk all at once.
==========
16.8: What do "Segmentation violation" and "Bus error" mean?
---
16.8: What do "Segmentation violation", "Bus error", and "General
protection fault" mean?
==========
Finally, the author of this FAQ list teaches a C class
and has placed its notes on the web; they are at
---
Finally, the author of this FAQ list once taught a couple of
C classes and has placed their notes on the web; they are at
==========
18.10: What's a good book for learning C?
---
18.10: What's a good book for learning C? What about advanced books
and references?
==========
The GNU libplot package maintains the same spirit and supports
many modern plot devices;
see http://www.gnu.org/software/plotutils/plotutils.html .
---
The GNU libplot library, written by Robert Maier, maintains
the same spirit and supports many modern plot devices; see
http://www.gnu.org/software/plotutils/plotutils.html .
==========
A: If the "size of a file" is the number of characters you'll be
able to read from it in C, it is difficult or impossible to
---
able to read from it in C, it can be difficult or impossible to
determine this number exactly.
==========
readdir() only returns file names; if you need more
---
readdir() returns just the file names; if you need more
information about the file, try calling stat().
==========
(Also, remember to call pclose().)
---
(Also, remember to call pclose() when you're done.)
==========
busy-wait, but this is only an option on a single-user, single-
tasking machine as it is terribly antisocial to any other
---
tasking machine, as it is terribly antisocial to any other
processes. Under a multitasking operating system, be sure to
==========
It is possible, and desirable, for *most* of a program to be
ANSI-compatible, deferring the system-dependent functionality to
a few routines in a few files which are rewritten for each
system ported to.
---
a few routines in a few files which are either heavily #ifdeffed
or rewritten entirely for each system ported to.
==========
or have the function return a structure containing the
desired values, or (in a pinch) consider global variables.
---
desired values, or (in a pinch) you could theoretically use
global variables.
==========
is not only clearer to the human reader, it is more likely to be
recognized by the compiler and turned into the most-efficient
code (e.g. using a swap instruction, if available).
---
code (e.g. perhaps even using an EXCH instruction).
==========
More information may be found in FORT.gz by Glenn Geers, available
via anonymous ftp from suphys.physics.su.oz.au in the src
directory.

cfortran.h, a C header file, simplifies C/FORTRAN interfacing on
many popular machines. It is available via anonymous ftp from
zebra.desy.de or at http://www-zeus.desy.de/~burow .
---
For FORTRAN, more information may be found in FORT.gz by Glenn
Geers, available via anonymous ftp from suphys.physics.su.oz.au
in the src directory. Burkhard Burow's header file cfortran.h
simplifies C/FORTRAN interfacing on many popular machines.
It is available via anonymous ftp from zebra.desy.de or at
http://www-zeus.desy.de/~burow .
==========
This FAQ list's maintainer also has available a list of a few
other commercial translation products, and some for more obscure
languages.
---
other translators.
==========
A: The contest is in a state of flux; see
---
A: The contest schedule varies over time; see
====================


Finally, here are a few questions which don't really need to be in
the posted-to-Usenet list every month. (As mentioned, though, they'll
live on in the web-based version.)

==========

1.22: How can I declare a function that can return a pointer to a
function of the same type? I'm building a state machine with
one function for each state, each of which returns a pointer to
the function for the next state. But I can't find a way to
declare the functions.

A: You can't quite do it directly. Either have the function return
a generic function pointer, with some judicious casts to adjust
the types as the pointers are passed around; or have it return a
structure containing only a pointer to a function returning that
structure.

==========

2.7: I heard that structures could be assigned to variables and
passed to and from functions, but K&R1 says not.

A: What K&R1 said (though this was quite some time ago by now) was
that the restrictions on structure operations would be lifted
in a forthcoming version of the compiler, and in fact structure
assignment and passing were fully functional in Ritchie's
compiler even as K&R1 was being published. A few ancient C
compilers may have lacked these operations, but all modern
compilers support them, and they are part of the ANSI C
standard, so there should be no reluctance to use them.

(Note that when a structure is assigned, passed, or returned,
the copying is done monolithically; the data pointed to by any
pointer fields is *not* copied.)

==========

13.14b: Does C have any Year 2000 problems?

A: No, although poorly-written C programs do.

The tm_year field of struct tm holds the value of the year minus
1900; this field will therefore contain the value 100 for the
year 2000. Code that uses tm_year correctly (by adding or
subtracting 1900 when converting to or from human-readable
4-digit year representations) will have no problems at the turn
of the millennium. Any code that uses tm_year incorrectly,
however, such as by using it directly as a human-readable
2-digit year, or setting it from a 4-digit year with code like

tm.tm_year = yyyy % 100; /* WRONG */

or printing it as an allegedly human-readable 4-digit year with
code like

printf("19%d", tm.tm_year); /* WRONG */

will have grave y2k problems indeed. See also question 20.32.

==========

13.24: I'm trying to port this A: Those functions are variously
old program. Why do I obsolete; you should
get "undefined external" instead:
errors for:

index? use strchr.
rindex? use strrchr.
bcopy? use memmove, after
interchanging the first and
second arguments (see also
question 11.25).
bcmp? use memcmp.
bzero? use memset, with a second
argument of 0.

==========

15.7: I have a pre-ANSI compiler, without stdarg.h. What can I do?

A: There's an older header, varargs.h, which offers about the
same functionality.

==========

18.5: How can I shut off the "warning: possible pointer alignment
problem" message which lint gives me for each call to malloc()?

A: The problem is that traditional versions of lint do not know,
and cannot be told, that malloc() "returns a pointer to space
suitably aligned for storage of any type of object." It is
possible to provide a pseudoimplementation of malloc(), using a
#define inside of #ifdef lint, which effectively shuts this
warning off, but a simpleminded definition will also suppress
meaningful messages about truly incorrect invocations. It may
be easier simply to ignore the message, perhaps in an automated
way with grep -v. (But don't get in the habit of ignoring too
many lint messages, otherwise one day you'll overlook a
significant one.)

No comments: