links to programming in the C language.
updated 2006-04-20
David is writing a book (YARMAC) on programming in the C language. (Ask me how it's going !) Here's some links to resources that go beyond the scope of that book.
Contents:
related local pages:
[FIXME: move the C programming stuff from linux.html and book.html to here. ]
consider moving YARMAC, my C book, to http://www.foogirl.de/C/FrontPage (found from a link on worldwidewiki) [offline ?]
Consider also moving this text to http://c2.com/cgi/wiki?CategoryCee and/or copying text there to YARMAC.
Or perhaps merging with Wikibooks: Programming in C http://en.wikibooks.org/wiki/Programming:C
Or perhaps merging with the GCC wiki http://gcc.gnu.org/wiki
latest news about C programming [FIXME: .... online discussion groups ...]
Since 1981, the mission of the C/C++ Users Group (CUG) has been focused on low-cost distribution shareware and freeware C/C++ source code. CUG launched the C/C++ Users Journal in 1983. We invented the term user supported software to describe this activity two decades before open source became an industry buzzword. The C/C++ Users Group is an independent organization that is impartial to compiler vendors or platforms. In recent years, CUG focuses primarily on cross-platform compatability with Unix, MS Windows, and others. We are the single largest resource for portable code on the planet.
...
Submit YOUR code to CUG!
Abstract: This article assumes you know the basics of the C language, and will introduce you to using gcc as a compiler. ... We also take a very brief look at using a debugger.
FAQ
To iterate over every element of an array in plain ANSI C, use
#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x))) for( i = 0; i < NUM_ELEM(array); i++ ) { /* do something with array[i] */ ; }
pages like this one: information about lots of different aspects of C programming (tutorials, libraries, C++, STL, style guides, etc.)
The "volatile" keyword is ``only'' needed to refer to non-RAM hardware. (serial ports, video RAM, ...).
But what a boring world this would be if all we had was RAM.
Date: Mon, 6 Aug 2001 16:54:12 -0500 Use of 'const' and 'volatile' http://www.arm.com/support.ns4/html/sdt_build!OpenDocument&ExpandSection=19#_Section19 Description The correct placement of the type qualifiers 'const' and 'volatile' can sometimes be confusing, especially when applied to a pointer or the thing it points to. Solution Here is a simple rule which may help: place 'const' (or 'volatile') *after* the thing you're saying is constant (or volatile). * to declare a constant integer, use 'int const xxx', instead of 'const int xxx'. * to declare a pointer to a constant integer, put 'const' after 'int' to get 'int const *ptr'. * to declare a constant pointer to an integer, put 'const' after '*' and get 'int * const ptr'. * to declare a constant pointer to a constant integer, use 'int const * const ptr'. * to declare a constant pointer to a volatile integer, use 'int volatile * const ptr'. The really nice thing about doing it this way is that you can see what the type is by simply reading *backwards* through the definition: int const xxx; | | | | | +----------> xxx is a | +---------------> constant +--------------------> integer int const *ptr; | | | | | | | +---------> ptr is a | | +-----------> pointer to a | +---------------> constant +--------------------> integer int * const ptr; | | | | | | | +--------> ptr is a | | +-------------> constant | +-----------------> pointer to an +--------------------> integer int const * const ptr; | | | | | | | | | +--> ptr is a | | | +-------> constant | | +-----------> pointer to a | +---------------> constant +--------------------> integer int volatile * const ptr; | | | | | | | | | +--> ptr is a | | | +-------> constant | | +-----------> pointer to a | +-----------------> volatile +-----------------------> integer For a real example of the application of 'const', see Placing (constant) jump tables in ROM. For an example of the use of 'volatile', see armcc/tcc: Placing C variables at specific addresses - memory-mapped peripherals. In fact, this method works for any type qualifier, including __packed, e.g. int __packed x and int *__packed x;
More about const: http://c2.com/cgi/wiki?ConstCorrectness
refactoring
Refactoring is a key part of XP (eXtreme Programming). It's been a major part of the Forth culture for years; the original reason Forth programmers started refactoring isn't relevant to most desktop or server applications, but they've discovered other benefits that apply to C (and practically every language).
Refactoring can be considered a form of functional program compression data_compression.html#program_compression .
DAV: ... In FORTH and Postscript, any ``block'' (a section of code that is only entered in one location and exited in one location) that is duplicated twice in the source can be factored out fairly easily... ... recognize that one function has been ``in-lined'' many places in the code, then split it out into a stand-alone version and replace all repeats with calls to that function. ... [FIXME: consider writing a program to find the ``longest'' duplicated code block ... or the ``most frequent'' duplicated code block ...] [FIXME: consider writing a ``program compressor'' to try to automatically factor all possible repeated blocks]
--Factoring ... a key to debugging and maintaining the code. Well factored code is easy to debug and maintain so the programmer is more effective with their time.
...
what you take away is more important than what you add. ... you end up adding a lot of stuff that you didn't intend to add originally ... You have to put in what you need but, unless you make an effort to take out what you don't, fat accumulates.
Chuck ... is compelled to experiment and improve his code. He is not against throwing something out if he finds a way to be more productive without it. ... he found a better way to solve the same problems those things were there to solve, they were no longer needed and so were just in the way. ...
... he didn't just take stuff out randomly or for no reason. He took stuff out after many years of extensive experimentation and consideration because either it was replaced by something that he considered better or he felt that it was just getting in the way and no longer needed at all.
...
Translating programs from one language to another can be done mechanically or by studying the implementation in one language and improving on it in the next. Don't translate when you have the opportunity to rewrite and improve. You can spend your time carefully designing code or trying to debug and improve thoughtless code. Translating without thinking is not thoughtful programming. Don't be afraid to think about the problem and what you are doing.
...
Thoughtful Programming and Forthby Jeff Fox http://www.ultratechnology.com/forth.htm
... contrary to a myth popular in the Forth community, calls in C are not slow...-- ``Compilation of Forth to C'' by Anton Ertl, Martin Maierhofer http://www.complang.tuwien.ac.at/projects/forth.html
Both "UI Style Guides" to make programs easier to use, and "Coding Standards" to make source code easier to understand and improve. Online Style Guides.
(also see HTML Style Guides) (also see user_interface.html)
contents:
Up: #style_guides
Up: #style_guides
When you call a function, you typically want it to do something -- -- but sometimes that something is physically impossible (for example, if you want to write a file to a CD-ROM, or create an array that's larger than the remaining free RAM, or ...). Most functions have a integer "return value" that indicates whether they succeeded or failed.
Some functions return 0 when they cannot (at the moment) do what you ask of them, and non-zero when the succeed (please don't do this). Those programmers made an intuitive association, connecting Boolean "true" with "success" and Boolean "false" with failure.
C functions often have many kinds of failure, but only one kind of success, so the *most common* C idiom for the return value is to call it a "error code" that indicates precisely which kind of error occurred (or 0 to indicate success). This way a program can just check with a boolean op if it just cares whether a function succeeded or failed, or it can look at the exact type of failure and do something about it. (for example, if a write to disk fails, you may want to do something different when the return value integer indicates "file is locked" vs. when it indicates "file doesn't exist").
Some functions can succeed in several different ways. One common idiom is to set the most significant bit to 1 if there is a error and clear it to 0 if the function succeeded. (i.e.,
if( my_function(...) < 0 ){ // handle error ... }else{ // Success ! ... };). Then the lower-order bits encode the type of success (or the type of failure) and where exactly this code was generated (sometimes the function you called had a immediate failure, sometimes it called some other function which ... failed 6 levels deep). The most common type of success returns the value 0 (sometimes called "S_OK"). (I hear this idiom is called a "HRESULT" or a "SCODE", and is commonly used in OLE programming and in the GhostScript program). All callers should check for error returns and, in general, propagate errors to *their* caller.
Up: #style_guides
(DAV suspects that, since well-written code is written for the audience of other humans, then really good styles for one language probably can be applied to any computer language ... except, of course, when that's working around a flaw in that language)
FORTH CODING RULES http://www.amleth.demon.co.uk/library/standard/fcoding.htm -- not just indentation, but suggestions for program testing, and ways of making it easier to extract documentation from comments.
[FIXME: Is this the same as]
``Optimizing Java for Maintainability'' by Jonathan Hardwick 1997 http://www-2.cs.cmu.edu/~jch/java/maintainability.html has some good tips, many of them apply to other languages.
Books Books on programming style:
Up: #style_guides
development tools: IDEs, documentation tools, ``lint'', etc.
various programs (tools) used to make writing programs easier / better.
I almost split out a section on just ``documentation and literate programming'' -- but documentation is something that needs to saturate every part of programming.
Here I list stand-alone programs. Elsewhere [FIXME:] I list libraries that you can compile into your own programs.
[IDEs, literate programming and documentation tools, lint, ...]
FunnelWeb is a powerful literate-programming macro preprocessor that enables you to weave programs and documentation together. ...
- Can be used with any programming language.
- Runs on most platforms (including GNU/Linux).
- Source available under a GNU licence.
- ...
- FunnelWeb user community mailing list.
... FunnelWeb is also a powerful general purpose text file preparation tool that has found many applications outside the area of literate programming. ...
malloc
, realloc
, calloc
,
free
and other memory management routines while providing
powerful debugging facilities configurable at runtime. These
facilities include such things as memory-leak tracking, fence-post
write detection, file/line number reporting, and general logging of
statistics.''
http://dmalloc.com/
by Gray Watson.
Seems to have a very free license.
malloc()
debugger for debugging
dynamic memory allocations, although it can also trace and profile calls to
malloc()
and free()
too. If you don't know what the
malloc()
function or operator new[]
do then this library
is probably not for you.
...
The mpatrol library ... is covered by the GNU Library General Public License.''
http://www.cbmamiga.demon.co.uk/mpatrol/
the standard template library (STL) [FIXME: shouldn't some of these be moved to the style guide section ?]
There are all kinds of little things in C that people get annoyed at. Here's some dialects of C that try to fix one or more of them. There's a few C interpreters (useful for testing and tweaking pieces of code, without a long edit-compile-run cycle), ...
-- Eric Steven Raymond http://www2.linuxjournal.com/lj-issues/issue73/3882.html /* http://www.linuxjournal.com/article.php?sid=3882 */One course I did not consider was going back to C as a default language. The days when it made sense to do your own memory management in a new program are long over, outside of a few specialty areas like kernel hacking, scientific computing and 3-D graphics -- places where you absolutely must get maximum speed and tight control of memory usage, because you need to push the hardware as hard as possible.
For most other situations, accepting the debugging overhead of buffer overruns, pointer-aliasing problems, malloc/free memory leaks and all the other associated ills is just crazy on today's machines. Far better to trade a few cycles and a few kilobytes of memory for the overhead of a scripting language's memory manager and economize on far more valuable human time. Indeed, the advantages of this strategy are precisely what has driven the explosive growth of Perl since the mid-1990s.
__pure
asserts that a function has no side effects.
http://www.nicholson.com/rhn/basic/ has several pointers to C interpreters
Beginner's All-purpose Symbolic Instruction Code
[FIXME: I'm not really that interested in BASIC any more ... is there a better place to put this stuff ?]
[FIXME:]... a very tiny BASIC language, called the VTL-09, ... Instructions on using the language may be found in _The MC 6809 Cookbook_, published by Tab Books. ... VTL-09 ... is ROMable. ... it's free, it can't be sold, and programs written for it must be given away. VTL-09 is not a commercial venture. ... Dick Heiser ...''
"Wizzdom" (Aussie newsletter) by Barry Klein about the 6502a -based WIZZARD game computer. http://creativemu.emuhq.com/articles.html
(see also Tiny C tiny_c )
68000 Tiny Basic Web Page by Gordon Brandly http://members.home.net/gbrandly/68ktinyb.html
Chipmunk Basic Home Page http://www.nicholson.com/rhn/basic/ has a list of pointers to other Basic interpreters with source code. Check out "structured Basic".
source code to some programs written in Tiny Basic http://www.code.archive.aisnota.com/
MoonRock compiler and development language http://www.rowan.sensation.net.au/moonrock.html "MoonRock is a BASIC-like language with several extensions. Produces small and tight executables (MS-DOS). 8086, 80186+ or 80386+ code. DOS real mode or DPMI protected mode. " "the compiler is written with MicroSoft's QuickBASIC and Visual BASIC for DOS. A new version of MoonRock is being rewritten from scratch, coded entirely in MoonRock. " also points to "SLC (Simple Little Compiler)" DAV: this seems to have some similarities to my "functional compression" ideas ...
comp.lang.basic.misc FAQ http://www.rahul.net/rhn/basic/basic.faq.txt
boolean operators vs. bitwise operators: with the convention that 0 = false, 1 = true, and boolean operators "<", ">", "=", etc all return 0 or 1, while "if()" accepts any non-zero as true, then:
-- recc. Jeffrey R. Fox 12/20/2000Phil Burk's pForth (http://www.softsynth.com/pforth/) is my choice ...
It isn't anywhere near as fast as GForth ...
If you want to mix C/C++ w/Forth under Windows, you can always put the C/C++ in a DLL and then call it from a native Forth like Win32Forth ... You can even make a Forth DLL so that your C/C++ mainline can call Forth. ...
P.P.P.S. Hey and if you want to substitute Java for C/C++, then take a look at FIJI, HolonJ, JEForth, etc. FIJI is a lot of fun, and HolonJ (shareware) is a complete programming environment.
P.P.P.P.S send me an email if you can't find one of these at www.forth.org.
Or check out PFE (the Portable Forth Environment) http://pfe.sourceforge.net/
...Abstract: This paper presents uCR, a C++ runtime package for embedded program development. We make the case that in certain situations embedded programming is best done without the aid of a conventional operating system. A programming environment in the form of a C++ runtime is presented, and the environment, including the C++ language, is evaluated for appropriateness. Important factors are code size, performance, simplicity and applicability to a wide range of embedded targets.
Assembly Code
When dealing with ``bare iron,'' some assembly code is inevitable. There is, for example, no reasonable way to implement thread switching entirely in C or C++, and in most processors interrupt and trap handlers must have assembly code to save the context of an interrupted thread and setup a fresh C/C++ calling sequence.
However, assembly code should typically be kept to a minimum. A human can do a good job of optimizing a small stretch of assembly code, but as the code grows, the human capacity to manage resource allocation becomes overwhelmed and the compiler performs better [than the human].
The paradox is that short assembly functions are more likely to be inefficient if placed in seperate source files, as the call and return overhead starts to overwhelm. What we really want is a way to write inline assembly code.
...
We to this day face people telling us that C++ generates inefficient code that cannot possibly be practical for embedded systems where speed matters. The criticism that C++ leads to bad executable code is ridiculous, but at the same time accurate. Poor style or habits can in fact lead to awful results. On the other hand, a skilled C++ programmer can write programs that match or exceed the quality of equivilent C programs written by equally skilled C programmers.
The development cycle of embedded software does not easily lend itself to the trial-and-error style of programming and debugging, so a stubborn C++ compiler that catches as many errors as possible at compile time significantly reduces the dependence on run-time debugging, executable run-time support and compile/download/test cycles. This saves untold hours at the test bench, not to mention strain on PROM sockets.
[FIXME: read]Abstract. Although C is a powerful system programming language that can deliver much the same control over devices as assembly language, it has deficiencies when it comes to scientific and engineering applications that require extensive numerical computing. C99, ratified as the ANSI/ISO C Standard (ISO/IEC IS 9899), is a milestone in C's evolution into a viable programming language for scientific and numerical computing. Among other features, C99 supports IEEE floating-point arithmetic, complex numbers, and variable-length arrays (VLAs) for numerical programming. ...
Newsgroup: alt.os.linux Subject: Re: NANO AND PICO!!! From: Giannis Georgalis compile-sig@spam.com Date: 28 Oct 2002 20:02:39 +0200 ... -- int main(void){int j=1234;/*(c)2002 jgeorgal */ char t[] ="<G> @abcdefghijklmnopqrstuvwxyz.\n"; char*i ="qhui<xfi.df rwgzfizjz.f rwgqqwqtigiz"; while(*i)((j+=strchr(t,*i++)-(int)t),(j%=sizeof t-1),(putchar(t[j])));return 0;}/* under GPL */
a full-featured Integrated Development Environment (IDE) for the C/C++ programming language. It uses Mingw port of GCC (GNU Compiler Collection) as it's compiler. Dev-C++ can also be used in combination with Cygwin or any other GCC based compiler. ... Delphi 6 Source code of Dev-C++ is available for free under the GNU General Public License (GPL)
[c reference manual # bibliography] ANSI specification X3.159-1989:Programming Language C,ANSI, 1430 Broadway, New York, NY 10018. Kernighan, B.W. and D.M. Ritchie, The C Programming Language, Second Edition, Prentice-Hall, Inc., 1988. _MATLAB Language Reference Manual: Version 5_ (c) COPYRIGHT 1984 - 1997 by The MathWorks, Inc. http://www.mathworks.com/
Most ANSI-compatible C compilers accept the following ASCII characters for both the source and execution character sets. ...
- The 26 lowercase Roman characters:
a b c d e f g h i j k l m n o p q r s t u v w x y z- The 26 uppercase Roman characters:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z- The 10 decimal digits:
0 1 2 3 4 5 6 7 8 9- The 30 graphic characters:
! # % ^ & * ( ) - _ = + ~ ' " : ; ? / | \ { } [ ] , . < > $
A warning is issued if the $ character is used when the compiler's strict ANSI mode option is specified.DAV: sometimes \? is needed to represent a literal question mark, to avoid unwanted triglyph (sp ?) interpretation. The same for \' and \" and \\ to represent a literal single and double quote and backslash inside a character literal or string literal.
- Five white space characters:
- Space ( )
- Horizontal tab (\t)
- Form feed (\f)
- Vertical tab (\v)
- New-line character (\n)
In character constants and string literals, characters from the execution character set can also be represented by character or numeric escape sequences. Section 1.8.3.3 and Section 1.8.3.4 describe these escape sequences.
The ASCII execution character set also includes the following control characters:
- New-line character (represented by \n in the source file),
- Alert (bell) tone ( \a )
- Backspace ( \b )
- Carriage return ( \r )
- Null character ( \0 )
The null character is a byte or wide character with all bits set to 0. It is used to mark the end of a character string. Section 1.7 discusses character strings in more detail.
The new-line character splits the source character stream into separate lines for greater legibility and for proper operation of the preprocessor.
`` Ncurses not only creates a wrapper over terminal capabilities, but also gives a robust framework to create nice looking UI (User Interface)s in text mode. It provides functions to create windows etc. Its sister libraries panel, menu and form provide an extension to the basic curses library. These libraries usually come along with curses. One can create applications that contain multiple windows, menus, panels and forms. Windows can be managed independently, can provide 'scrollability' and even can be hidden. ''
http://www.softintegration.com/products/ Does this really work on Palm Pilots ?Ch is a superset of C language. It parses and executes C code directly without intermediate code or byte code. It does not distinguish interpreted code from compiled C/C++ code. Ch is the most complete C interpreter in existence. Ch is embeddable in other application programs and hardware.
programming on DSPs and other systems where a char
is not 8 bits.
That's the entire point of the CHAR_BIT macro (sometimes called the BITS_PER_UNIT ).
See also
http://c2.com/cgi/wiki?CompilerQuestion
I fail to see the problem at
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=75195
.
Sure, a char
may be 32 bits.
But if you know exactly the format you need to write something out,
then write it out 8 bits at a time.
char packet_byte_array[my_string_length]; // OK if this compiler uses 32 bits for each char -- we'll only use the bottom 8 bits. for(int i=0; i < NUM_ELEM(my_string); i++){ int putc((int)(packet_byte_array[i] & 0xff), the_stream); // only write the bottom 8 bits of each char }
http://mail.python.org/pipermail/python-dev/2003-December/041261.html
how about adding
#if UCHAR_MAX != 255 #error "Python's source code currently assumes 8-bit characters." #endif...
instead of trying to "fix stuff" for a case that's probably never going to arise, and that can't really be tested anyway until it does, I'd add a block like this everywhere we know we're relying on 8-bit char:
#ifdef HAS_FUNNY_SIZE_CHAR #error "The following code needs rework when a char isn't 8 bits" #endif /* A comment explaining why the following code needs rework * when a char isn't 8 bits. */
-- Skip Montanaro and Tim Peters http://mail.python.org/pipermail/python-dev/2003-December/041276.html http://mail.python.org/pipermail/python-dev/2003-December/041250.html
If you see code that would break on a 16-bit char machine, consider adding
#if UCHAR_MAX > 255 #error this code not qualified for your machine #endifto that C file, rather than wait for it to break at run time.
-- Larry Doolittle http://www.busybox.net/lists/busybox/2005-October/016479.html
More on when char != 8 bits:
Subject: Re: Unsigned Char Date: 20 Nov 1998 00:00:00 GMT From: "Steve Waldo" Organization: Rockwell Automation Newsgroups: comp.lang.c.moderated References: 1 , 2 , 3 , 4 , 5 Does the standard really say "byte"? In K&R (admittedly not ANSI!) it says that a *char* is big enough to hold any character. Also, sizeof(char) must return 1. This would imply to most that a char is a byte. However, I'm developing code for a DSP for which each address returns a 32 bit value. It can't access specific bytes or words. It's ANSI C compiler returns 1 for sizeof(char), as required, but also returns 1 for sizeof(short), sizeof(int), and sizeof(long)! All are 32 bit values. It seems like a waste to have 32 bit characters, but as far as I can tell, it doesn't break the standard. Steve --------------------------------------------------------------------------- >>The char is 1 byte, by definition :-) > >That depends on your definition of byte. The only definition relevant here is that of the C language. This specifies a byte to be the unit of storage required to hold a member of the basic character set, or IOW a char. -- comp.lang.c.moderated - clcm@plethora.net
Subject: Re: Unsigned Char Date: 27 Nov 1998 00:00:00 GMT From: christian.bau@isltd.insignia.com (Christian Bau) Organization: Insignia Solutions Newsgroups: comp.lang.c.moderated References: 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ... peter burka < peter at purpledreams.com > wrote: > > union { > > int i; > > unsigned char rep[sizeof int]; > > }; > > > > as a method of accessing the raw memory of i. > Does the standard actually require that such a union work? > I thought that reading a member of a union which was not the > most recently written member yielded undefined behaviour. > So a conforming implementation could treat unions just like > structs if it really wants to. I dont think it works. If you store something into i, then the contents of rep is undefined, and you are not allowed to read it. For example, if the compiler knows the last value you stored into rep [0], it can assume that after storing into i that value is still there and unchanged. So "accessing the individual bytes of i through rep" does NOT work. But a conforming implementation cannot treat unions as structs, because all elements must have the same address. (void *) &some_union.i == (void *) some_union.rep is guaranteed. To access individual bytes, you can use memcpy; that is guaranteed to work. You can also use (char *) &i. There is a special rule that says basically (for example) an object that IS really an int can be accessed as an int, or an unsigned int, or a char, but not as something else. > (Also, what would pointers look like on the Cray? > Does sizeof(char*) == sizeof(int*)? Presumably > sizeof(void*) >= sizeof(char*)?) void* and char* must have the same representation. I think it is quite likely that char* uses more bits than int*, but you probably have something like int* = 48 bits used plus 16 bits unused, char* = 48 bits used + 3 bits specifying a character + 13 bits unused, so their sizes will be the same. -- comp.lang.c.moderated - clcm@plethora.net [FIXME: move to endian_faq.html ?] Subject: Re: Unsigned Char Date: 23 Nov 1998 00:00:00 GMT From: Dan.Pop@cern.ch (Dan Pop) Organization: CERN European Lab for Particle Physics Newsgroups: comp.lang.c.moderated References: 1 , 2 , 3 , 4 , 5 , 6 ... "Steve Waldo" writes: >Does the standard really say "byte"? Yup, and I posted the relevant definition from the standard. >However, I'm developing code for a DSP for which each address returns a 32 >bit value. It can't access specific bytes or words. It's ANSI C compiler >returns 1 for sizeof(char), as required, but also returns 1 for >sizeof(short), sizeof(int), and sizeof(long)! All are 32 bit values. It >seems like a waste to have 32 bit characters, but as far as I can tell, it >doesn't break the standard. Indeed, it doesn't break the standard. Your implementation has a 32-bit byte. Quite common for freestanding implementations for this kind of processors. The "classic" Cray processors have 64-bit words (and each address is a word address). The C implementation packs 8 8-bit chars in a word. The char pointers contain both an address and the "offset" inside the word where the char is stored. All the other types are 64-bit. It's very hard to avoid the 8-bit char in a modern hosted implementation. Dan -- Dan Pop CERN, IT Division Mail: CERN - EP, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland -- comp.lang.c.moderated - clcm@plethora.net Subject: Re: Unsigned Char Date: 13 Nov 1998 00:00:00 GMT From: Niall Smart Organization: EUnet Ireland customer Newsgroups: comp.lang.c.moderated References: 1 > What is the difference between a signed and unsigned character in ANSI C? > (Besides the obvious). Assuming an 8-byte character and 2's complement representation the obvious difference is that an unsigned character will hold from 0 to 255 and a signed character will store integers from -128 to 127. > Why would anyone need to use an unsigned char? Perhaps some character sets out there use negative numbers to represent certain characters, I haven't come across any but presumably they exist. > I'm assuming that for most implementations, signed and unsigned char are > the same size. AFAIK ANSI C requires this (for all types which can be signed or unsigned). > Does C treat the two different? Yes, a signed character will be sign extended when promoted, for example, assuming sizeof(int) == 4 the following program: #include <stdio.h> #include <stdlib.h> int main() { unsigned char uc = 0xFF; signed char sc = 0xFF; printf("%d %d %u %u", (int) uc, (int) sc, (unsigned) uc, (unsigned) sc); return EXIT_SUCCESS; } will print "255 -1 255 4294967295". Observe that the most significant bit of sc (1) is extended when it is converted to a signed or unsigned integer, so (unsigned) sc == 0xFFFFFFFF or UINT_MAX. > Could you have a "negative" character? Yes, ANSI C does not define any character sets nor require all the characters in a character set to be positive. Regards, Niall -- comp.lang.c.moderated - clcm@plethora.net Subject: Re: Unsigned Char Date: 16 Nov 1998 00:00:00 GMT From: Dan.Pop@cern.ch (Dan Pop) Organization: CERN European Lab for Particle Physics Newsgroups: comp.lang.c.moderated References: 1 , 2 ... Niall Smart <nialls at euristix.ie> writes: >> What is the difference between a signed and unsigned character in ANSI C? >> (Besides the obvious). > >Assuming an 8-byte character and 2's complement representation the The char is 1 byte, by definition :-) >obvious difference is that an unsigned character will hold from 0 to 255 >and a signed character will store integers from -128 to 127. > >> Why would anyone need to use an unsigned char? > >Perhaps some character sets out there use negative numbers to represent >certain characters, I haven't come across any but presumably they exist. The most popular 8-bit character set, Latin-1 (ISO 8859.1) has plenty of negative characters on implementations where plain char is signed: ues5:~/tmp 206> cat test.c #include <stdio.h> int main() { char c = 'é'; printf("%c = %d\n", c, c); return 0; } ues5:~/tmp 207> cc test.c ues5:~/tmp 208> ./a.out é = -23 >> Does C treat the two different? > >Yes, a signed character will be sign extended when promoted, Nope. The value of a signed char (no idea what a "signed character" might be) will be preserved, when promoted. This can be achieved by sign extension on certain representations, but definitely not on the sign-magnitude representation. >for example, >assuming sizeof(int) == 4 the following program: > >#include <stdio.h> >#include <stdlib.h> > >int >main() >{ > unsigned char uc = 0xFF; > signed char sc = 0xFF; > > printf("%d %d %u %u", (int) uc, (int) sc, (unsigned) uc, (unsigned) sc); > > return EXIT_SUCCESS; >} > >will print "255 -1 255 4294967295". Maybe, maybe not. The result of assigning 0xFF to an 8-bit signed char is implementation-defined. Regardless of which representation is used. Dan -- Dan Pop CERN, IT Division Mail: CERN - EP, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland -- comp.lang.c.moderated - clcm@plethora.net
/* Note: Changing the value of HASH_TABLE_DEPTH_BITS is the ONLY thing you */ /* have to do to change the depth, so go ahead and recompile now! */ /* Note: I have tested LZRW3-A for DEPTH_BITS=0,1,2,3,4 and a few other */ /* values. However, I have not tested it for 12 as I can't wait that long! */ #define HASH_TABLE_DEPTH_BITS (3) /* Must be in range [0,12]. */
Please document each constants you define, so the maintainer (perhaps a future you) knows which kind of ``constant'' this is:
make
...
test harnesses
...
abstract data types
...
object-oriented programming (OOP)
... the assert() macro ...
VISTA is a static source code analysis tool. It provides a graphical front end to assist security analysits in discovering and tracking down security flaws at the source code level. Vista does this by providing several ways to navigate through large amounts of source code using mouse clicks. Vista also provides multiple views of the static structure of the program under analysis. This includes the ability to view the source code, caller and callee lists, and flow/dependance graphs.
I've successfuly used it in an embedded system
Editor writers, if your program runs out of memory, give the user a chance to save the files. This has been a public service announcement. Thank you.-- jutta http://kbs.cs.tu-berlin.de/~jutta/swd/paint.html
The Top 10 Ways to get screwed by the "C" programming languageby Dave Dyer http://www.andromeda.com/people/ddyer/topten.html
The case against Cby P.J. Moylan 1993 http://www.modulaware.com/mdlt35.htm
Now, modular programming is possible in C, but only if the programmer sticks to some fairly rigid rules:
- Exactly one header file per module. The header should contain the function prototypes and typedef declarations to be exported, and nothing else (except comments).
- The comments in a header file should be all that an external caller needs to know about the module. There should never be any need for writers to know anything about the module except what is contained in the header file.
- Every module must import its own header file, as a consistency check.
- Each module should contain #include lines for anything being imported from another module, together with comments showing what is being imported. The comments should be kept up-to-date. There should be no reliance on hidden imports which occur as a consequence of the nested #include lines which typically occur when a header file needs to import a type definition or a constant from elsewhere.
- Function prototypes should not be used except in header files. (This rule is needed because C has no mechanism for checking that a function is implemented in the same module as its prototype; so that the use of a prototype can mask a "missing function" error.)
- Every global variable in a module, and every function other than the functions exported via the header file, should be declared static.
- The compiler warning "function call without prototype" should be enabled, and any warning should be treated as an error.
- For each prototype given in a header file, the programmer should check that a non-private (i.e. non-static, in the usual C terminology) function with precisely the same name has its implementation in the same module. (Unfortunately, the nature of the C language makes an automatic check impossible.)
- Any use of grep should be viewed with suspicion. If a prototype is not in the obvious place, that's probably an error.
- Ideally, programmers working in a team should not have access to one another's source files. They should share only object modules and header files.
Now, the obvious difficulty with these rules is that few people will stick to them, because the compiler does not enforce them.
read only.In embedded systems, there is a huge difference, which will become clear. " "assert() is important (even in embedded systems)" has some good points on when *not* to write ANSI C. (Perhaps add "When Not to Write ANSI C" chapter to YARMAC).
Here is a pretty simple proposal for C. This can avoid the scanf anomalies and greatly simplify the run-time package for embedded systems. cstdio_c.htmhttp://cbfalconer.home.att.net/
The tendency of the undisciplined C programmer to set arbitrary but supposedly generous static limits on table sizes (defined, if you're lucky, by constants in header files) rather than taking the trouble to do proper dynamic storage allocation. If an application user later needs to put 68 elements into a table of size 50, the afflicted programmer reasons that he or she can easily reset the table size to 68 (or even as much as 70, to allow for future expansion) and recompile.
I prefer this:
short mainDepth = GetMainDevice() [0]-> gdPMap [0]-> pixelSize;to this:
short mainDepth = (**(**GetMainDevice()).gdpMap).pixelSize;
distcc is a program to distribute compilation of C, C++, Objective C or Objective C++ code across several machines on a network. distcc should always generate the same results as a local build, is simple to install and use, and is often two or more times faster than a local compile. ... distcc is not itself a compiler, but rather a front-end to the GNU C/C++ compiler (gcc), or another compiler of your choice.
Bjarne Stroustrup http://www.research.att.com/~bs/ designed and implemented the C++ programming language.
Coronado Enterprises tutorials http://www.swcp.com/~dodrill/ tutorials for Ada, C, C++, Pascal.
Using and Porting GNU CC http://www.dfv.rwth-aachen.de/doc/gnu/gcc/gcc_toc.html
On Legacy Applications and Previous Work http://cuiwww.unige.ch/OSG/people/jvitek/Compilers/Year94/msg00305.html
http://cuiwww.unige.ch/OSG/people/jvitek/Compilers/Year94/msg00964.html a simple symbol usage analyzer (lists each symbol, noting all files where it is defined and used) (in PERL) ( for looking at C code).
C++-pretty-printer wanted !!! http://cuiwww.unige.ch/OSG/people/jvitek/Compilers/Year94/msg01247.html
...
Our unconscious association of elegance with luxury may be one of the origins of the ... tacit assumption that it costs to be elegant. To show that it also pays to be elegant is one of my prime purposes. ...
Even under the assumption of flawlessly working machines we should ask ourselves ... "What measures can we take to increase our confidence that the results produced are indeed the results intended ?"
...
... In the design of programming languages ... considering "what the machine can do." Considering, however, that the programming language is the bridge between the user and the machine -- that it can, in fact, be regarded as his tool -- it seems just as important to take into consideration "what Man can think." ...
The technique of mastering complexity has been known since ancient times: Divide et impera (Divide and rule). ...
... I have only a very small head and must live with it. I, therefore, see the dissection technique as one of the rather basic patterns of human understanding ...
...
... After the abolishment of the goto statement there are only two ways in which a program may fail to stop: either by infinite recursion, i.e., through the procedure mechanism, or by the repetition clause. This simplifies the inspection ...
... the then prevailing opinion that the problems of language design and implementation were mostly a question of compromises: every new convenience for the user had to be paid for by the implementation, either in the form of increased trouble during translation, or during execution or during both. ... I am not going to deny the possibility of a conflict ... but ... I am of the opinion that it is worthwhile to investigate to what extent the needs of Man and Machine go hand in hand and to see what techniques we can devise for the benefit of all of us. ...
One of my principles here is that a program should not occupy too much space on the screen when it is being edited. The brain is only capable of holding so much information, and the more context that can be displayed the easier the code will be to grasp. It is, however, wise to limit oneself to 80 characters per line: many printers do not make a good job of printing longer lines.
...
Indexing things from zero (and that includes using a `little endian' convention) often simplifies matters.
...
started 2000-12-29:DAV: David Cary.
Return to index // validate // end http://david.carybros.com/html/c_programming.html /* was http://rdrop.com/~cary/html/c_programming.html */