Books on developing portable C suites

J

James Harris

Hi,

Can someone recommend a book that will teach me how to
approach C programming so that code is modularised, will compile
for different environments (such as variations of Unix and
Windows), will be robust etc.

As an example, I am developing a BSD Sockets suite which I want
to run under various Unixes, including the Zaurus version of
Linux, and also run parts of it under Windows. My thought is to
have the system calls as libraries somehow but without obscuring
the familiarity of the main code.

I want to be able to run
modules stand-alone (such as the module which converts a text
SNMP OID to ASN.1 encoding) but also use the same code from
within other modules. The ideal solution would be some sort of
dynamic linking, if it is fast enough. It also should be not
cumbersome to configure. Questions arise such as how do I locate
component modules - env var?, path?, locate with main module?
etc.

There's more to the need than that above. I don't need book on
how to use printf, pointers etc. There are hundreds of them. I
need something to go beyond coding and on to building complete
systems in C.

Hope someone can help.
Thanks,
James
 
S

Sam Hobbs

Hi,

Can someone recommend a book that will teach me how to
approach C programming so that code is modularised, will compile
for different environments (such as variations of Unix and
Windows), will be robust etc.
<snip>

A search for Title="Portable C" on amazon yielded the following;
probably can find more with a little digging and some more targeted
searches perhaps on Google.

Portable C (Prentice Hall Software Series)
by Henry Rabinowitz, Chaim Schaap (Contributor)
Out of Print--Limited Availability

Portable C and Unix System Programming (Prentice-Hall Software Series)
by J.E. Laping, J. E. Lapin
Out of Print--Limited Availability


Portable C Software
by Mark R. Horton
Out of Print--Limited Availability

Developing C Language Portable System Call Libraries/Book and Disk
by Matt Weisfeld
Out of Print--Limited Availability

Information Technology-Portable Operating System Interface (Posix):
System Application Program Interface (Api) (C Language)
by IEEE (Paperback - January 1997)

Solutions to Systems Portability in C and C++: Your Guide to Writing
Truly Portable Applications/Book and Disk
by John L. Bradberry, John E. Swanke
Out of Print--Limited Availability

Portable C
(Paperback - February 1990)
Special Order, no author given
 
E

Eric Bernard

James Harris said:
Hi,

Can someone recommend a book that will teach me how to
approach C programming so that code is modularised, will compile
for different environments (such as variations of Unix and
Windows), will be robust etc.

As an example, I am developing a BSD Sockets suite which I want
to run under various Unixes, including the Zaurus version of
Linux, and also run parts of it under Windows. My thought is to
have the system calls as libraries somehow but without obscuring
the familiarity of the main code.

I want to be able to run
modules stand-alone (such as the module which converts a text
SNMP OID to ASN.1 encoding) but also use the same code from
within other modules. The ideal solution would be some sort of
dynamic linking, if it is fast enough. It also should be not
cumbersome to configure. Questions arise such as how do I locate
component modules - env var?, path?, locate with main module?
etc.

There's more to the need than that above. I don't need book on
how to use printf, pointers etc. There are hundreds of them. I
need something to go beyond coding and on to building complete
systems in C.

Hope someone can help.
Thanks,
James

Hi James,
Unfortunately, programming 100% portable code ties you down to what the
ISO/IEC standard says, which does not include support for internet sockets.
I do not think buying a book on the topic (if there are any) is well-worth
it. You just need a few pointers, and lots of documentation. I suggest you
purchase a copy of the standard (only $18 USD in PDF format, see
www.iso.org.) That will give you *what* is portable and what not.

For the non-standard libraries you use such as Internet sockets, you can
build your code in such a #ifdef manner that it will compile without any
modification on all platforms, as follows:

#ifdef _WIN32
#include <winsock2.h>
#else
#include <net/socket.h> /* have no idea what the headers are for unix's,
but they aren't the same */
#endif

Secondly, you can use macros to hide the system-specific function calls and
other stuff too.

This may sound like a lot of work, but it's totally possible to do in a fair
amount of time.
If you need help on more specific questions on the same topic, don't be shy
to ask again to the group. You can also refer to portable libraries' source
code to see how they do it.
 
E

Eric Bernard

Oh one more thing, it depends on the compilers you use.
As you know, most unix's use gcc which was ported to windows (-ish) and may
lessen your work for a few things

I beleive its name is Mingw, but I could be wrong.
 
R

Randy Howard

"James Harris" said:
Can someone recommend a book that will teach me how to
approach C programming so that code is modularised,

One of the few books that seems to focus on coding for libraries
and reuse is:

"C Interfaces and Implementations, Techniques for Creating Reusable
Software", David R. Hanson, Addison-Wesley

It does cover a lot of the issues involved, although you may find
that you don't agree with everything said. It primarily focuses on
ADT design, interfaces, and sample implementations of a number of
well-known data structures using the author's method.
 
R

Richard Heathfield

[Cross-posted to far too many places. Followups set to comp.lang.c]

James Harris said:
Conditional compilation and macros is the kind of thing I had in
mind. I would put any conditional parts in libraries in
preference to the main code. That presents problems to me also.
For example, good practice regarding where to place those
libraries. I currently use

#include "../libs/lib1.h"

or the like. That expects the libraries to be in a sibling
directory. Is that good or is there a better practice?

Well, it assumes that you're using MS-DOS, Unix, or some derivative thereof.
Not all filesystems use the familiar Unix pathname syntax. If you really
are aiming for "portable", this isn't the strategy you're looking for.

Some people go the #ifdef route. I prefer the "these are the source files
that need to be rewritten for each new platform" route. The trick is to
keep their number and size to a minimum.

<snip>
 
D

Douglas A. Gwyn

Eric said:
Oh one more thing, it depends on the compilers you use.
As you know, most unix's use gcc which was ported to windows (-ish) and may
lessen your work for a few things

Actually compiler-specific extensions are rarely necessary,
especially when his stated goal was source portability.
The main thing he needs to tackle is the provision of
library (API) support across different platforms, not the
base language. There are multi-platform APIs for some
facilities (including sockets), but not for everything.

Another approach is to build the application around a
common operating environment (such as Inferno) and then
worry only about porting the environment, not the apps.
 
D

Douglas A. Gwyn

James said:
For example, good practice regarding where to place those
libraries. I currently use
#include "../libs/lib1.h"
or the like. That expects the libraries to be in a sibling
directory. Is that good or is there a better practice?

There is no really good *guaranteed portable* solution.
The usual practice is to #include "lib1.h" and then set
some include-path variable in the compilation environment,
e.g. in a "project" configuration file or a "makefile" to
the right place for the particular installation. All the
platforms I work with these days support something along
those lines.
 
J

James Kuyper

Eric Bernard said:
Hi James,
Unfortunately, programming 100% portable code ties you down to what the
ISO/IEC standard says, which does not include support for internet sockets.

It doesn't include a lot of things; sockets are just the beginning.
I do not think buying a book on the topic (if there are any) is well-worth
it. You just need a few pointers, and lots of documentation. I suggest you
purchase a copy of the standard (only $18 USD in PDF format, see
www.iso.org.) That will give you *what* is portable and what not.

Not really. The standard specifies precisely what you can count on
portably, but you have to be very familiar with the standard to
realize all of the implications of what it doesn't say. What most
programmers need is a book which actually explains those implications.
More important, it needs to explain what should be done about them.

For example, I have some code which is conceptually similar to the
following:

/* #defines NUM_ENTRIES, fun1() */
#include "my_header.h"

/* Third party library header. Contains a typedef for PGSt_integer. */
#include "PGS_types.h"

void func2(PGSt_integer array[NUM_ENTRIES])
{
long larr[NUM_ENTRIES];
int i;
for(i=0; i<NUM_ENTRIES; i++)
larr(i) = (long)array;
fun1(larr);
for(i=0; i<NUM_ENTRIES; i++)
array = (PGSt_integer)larr;
}

If you look at PGS_types.h, you'll find that PGSt_integer is a typedef
for 'long int'. Therefore, why did I bother with the for loops? Why
not simply call fun1(array)? The reason is more a matter of social
dynamics than of the standard: the fact that PGSt_integer is a typedef
implies that it might be changed at some time in the future, or even
on a different platform (the installation script for this particular
third party library installs different versions of the header files on
different platforms, so you can't even figure out all the
possibilities by following the #if statements in the header).

Since the typedef makes it possible for me to write code in a way that
will work no matter what size integer they use, the fact that they've
bothered to define a typedef obligates me to write my code that way,
at least if I want it to be portable.
For the non-standard libraries you use such as Internet sockets, you can
build your code in such a #ifdef manner that it will compile without any
modification on all platforms, as follows:

#ifdef _WIN32
#include <winsock2.h>
#else
#include <net/socket.h> /* have no idea what the headers are for unix's,
but they aren't the same */
#endif

That will NOT work on all platforms; only on Windows and Unix-like
platforms. The programming world is a lot bigger than that.
 
M

Malcolm

James Harris said:
Can someone recommend a book that will teach me how to
approach C programming so that code is modularised, will compile
for different environments (such as variations of Unix and
Windows), will be robust etc.
Buy a copy of C Unleashed. One of the authors, Mr Heathfield, is a reg here
and will be more than happy to answer any queries raised :)
 
B

Bjorn Reese

Eric said:
For the non-standard libraries you use such as Internet sockets, you can
build your code in such a #ifdef manner that it will compile without any
modification on all platforms, as follows:

#ifdef _WIN32

For a tentative list of pre-defined compiler macros see

http://predef.sourceforge.net/
 
A

Ajoy K Thamattoor

Conditional compilation and macros is the kind of thing I had in
Well, it assumes that you're using MS-DOS, Unix, or some derivative thereof.
Not all filesystems use the familiar Unix pathname syntax. If you really
are aiming for "portable", this isn't the strategy you're looking for.

Some people go the #ifdef route. I prefer the "these are the source files
that need to be rewritten for each new platform" route. The trick is to
keep their number and size to a minimum.

A better strategy would be to always just use:
#include "lib1.h"
and then explicitly specify the include path directories in the
compiler invocation.
This requires disciplined programming to ensure you don't end up
including the wrong file because of duplicate .h filenames in different
directories (in big projects with multiple coders, this is a real
concern).
The standard doesn't specify either the syntax of include
pathnames, or the search path semantics for included files (there are
some very weak assertions regarding the differences between <> and ""
style inclusions, but they amount to nothing much that is usable). It is
considered out of scope, even though, in reality, the UNIX style names
are supported by compilers even on platforms with a different path name
syntax.

Ajoy.
 
R

Richard Heathfield

Ajoy said:
A better strategy would be to always just use:
#include "lib1.h"
and then explicitly specify the include path directories in the
compiler invocation.

I agree that that's a decent strategy, but it doesn't actually conflict with
anything I said, so I'm not sure why you say it's "better".
This requires disciplined programming to ensure you don't end up
including the wrong file because of duplicate .h filenames in different
directories (in big projects with multiple coders, this is a real
concern).

As you say, that's a discipline issue.
The standard doesn't specify either the syntax of include
pathnames, or the search path semantics for included files (there are
some very weak assertions regarding the differences between <> and ""
style inclusions, but they amount to nothing much that is usable). It is
considered out of scope, even though, in reality, the UNIX style names
are supported by compilers even on platforms with a different path name
syntax.

Are you absolutely sure that Unix-style names are supported on, say, OS390?
 
J

James Harris

Much thanks to all who responded, though not many had any book
suggestions(!) I've ordered the following books,

The C Programming Language (Prentice Hall Software Series)
The Practice of Programming (APC)
Safer C: Developing Software for High-integrity and
Safety-critical Systems
C Interfaces and Implementations: Techniques for Creating
Reusable Software
Portable C (Prentice Hall Software Series) [Paperback] by
Rabinowitz, Henry (second hand)
Code Complete: A Practical Handbook of Software Construction
C Unleashed

As a general note from looking for books on C the truth seems to
be that many that I would have preferred were no longer
available. As the Portable C books that Sam found illustrate
these are no longer in print. There seemed to be a few C++ books
of the kind I want but at the moment I'll stick with C.

Maybe C++ another time, once my bank manager is speaking to me
again....<g>

Cheers,
James

"James Harris" <no.email.please> wrote in message
Hi,

Can someone recommend a book that will teach me how to
approach C programming so that code is modularised, will compile
for different environments (such as variations of Unix and
Windows), will be robust etc.

As an example, I am developing a BSD Sockets suite which I want
to run under various Unixes, including the Zaurus version of
Linux, and also run parts of it under Windows. My thought is to
have the system calls as libraries somehow but without obscuring
the familiarity of the main code.

I want to be able to run
modules stand-alone (such as the module which converts a text
SNMP OID to ASN.1 encoding) but also use the same code from
within other modules. The ideal solution would be some sort of
dynamic linking, if it is fast enough. It also should be not
cumbersome to configure. Questions arise such as how do I locate
component modules - env var?, path?, locate with main module?
etc.

There's more to the need than that above. I don't need book on
how to use printf, pointers etc. There are hundreds of them. I
need something to go beyond coding and on to building complete
systems in C.

Hope someone can help.
Thanks,
James
 

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,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top