Aspects of the C Programming Language, Slides of Computers and Information technologies

Various aspects of the c programming language, including its pros and cons, portability, speed, limitations, bad practices, the c standard, and abstraction. It also discusses the use of shared libraries and the concept of encapsulated types in c.

Typology: Slides

2010/2011

Uploaded on 09/06/2011

stifler_11
stifler_11 🇬🇧

4.6

(9)

272 documents

1 / 36

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
C, slide 1
C
Ian Holyer
Ian Holyer
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24

Partial preview of the text

Download Aspects of the C Programming Language and more Slides Computers and Information technologies in PDF only on Docsity!

C, slide 1

C

Ian Holyer

Ian Holyer

ASIDE on C, slide 2

History of C

This chapter has some specific topics, and encourages

you to continually extend your own understanding

C is regarded as an old language, but it was developed

for Unix in about 1972, within living memory

Before C there was BCPL, with platform independence,

dynamic loading, networking, auto-documenting, ...

C was 4 steps backwards! But it became standard and

weaned programmers off assembly language

C is the most durably popular language ever, and it is

still the best language to use in many circumstances, see

http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

ASIDE on C, slide 4

Pros and Cons

C is not platform independent and not high level (OO or

declarative) and lacks extensive standard libraries

C is good for dealing with devices & operating systems,

doing raw number-crunching or graphics-crunching, and

for run-time systems (e.g. for Java and Haskell!)

C is much more structured and expressive than its main

low level rival, which is assembly language

C is portable, meaning you can move programs by

making a few changes and recompiling, not rewriting

The best compiler, gcc, is available everywhere, free,

open source and generally excellent, see:

http://gcc.gnu.org/

ASIDE on C, slide 5

Portability

A typical C application makes use of a large number of

libraries, headers, tools, and other facilities

These vary enormously between platforms: whether

installed, where, version, configuration, and so on

Standard utilities configure and ( g ) make from GNU help

with porting between versions of Unix

Running configure is an eye-opener: it makes hundreds of

tests, documenting all the unnecessary bugs and platform

differences between versions of Unix

On other platforms, tools like Cygwin allow Unix/C

programs to run, but they are clunky, so realistically you

have to target non-Unix platforms explicitly (e.g. using

TCL and GTK)

ASIDE on C, slide 7

Compiler Technology

Optimisation techniques can estimate the speed of

instruction sequences accurately, and find the 'best'

instruction sequence for small, local sections of code

This includes instruction sequences that no assembly

language programmer would ever think of

Imagine a contest between gcc and the best assembly

language programmers over a variety of programs

The programmers would win occasionally, but the

compiler would win hands down overall

You end up with a non-intuitive conclusion

C beats assembly language

ASIDE on C, slide 8

Speed Limitations

C is fast, but it is low level so there are optimisations,

based on the compiler 'understanding' the intention of

the programmer, that cannot be applied, e.g. aliasing

The compiler cannot tell where pointers are pointing

to, so if you have a function with two array arguments,

C cannot tell whether the two areas of memory overlap

or not, preventing various code re-ordering

optimisations

C cannot optimise properly across modules, and cannot

even do general tail-call optimisation

Higher level languages like Java and Haskell may

catch up and even overtake C in the long run, in the

same way C overtook assembly language

C, slide 10

The C Standard

The standard for C used to be the K&R book The standard for C used to be the K&R book

It is now C99 which you can find at:

It is now C99 which you can find at: http://www.open-

http://www.open-

std.org/jtc1/sc22/wg14/www/standards std.org/jtc1/sc22/wg14/www/standards

Not all of C99 is supported by gcc, see

Not all of C99 is supported by gcc, see wikipedia: C

wikipedia: C

and

and google: open source development with C

google: open source development with C and

and

google: status of C99 features in gcc google: status of C99 features in gcc

C99 supports some new features:

C99 supports some new features:

  • comments starting with // (like C++/Java)
  • declarations inside code, including for (int i=0;...)
  • long longs (64 bit) and booleans with <stdbool.h>
  • struct values, e.g. (struct Point) { 1, 2 }
  • the inline keyword

C, slide 11

Compiling with GCC

The right way to compile a program with gcc is: The right way to compile a program with gcc is:

gcc -std=c99 -pedantic -Wall -O

The The -std=c -std=c flag replaces -ansi flag replaces -ansi

The

The -pedantic

-pedantic avoids non-standard gcc extensions

avoids non-standard gcc extensions

  • The The -Wall -Wall switches on all warnings switches on all warnings

The The -O -O optimizes the code: optimizes the code:

without it (or -O at least) gcc produces terrible code

  • with it, programs take longer to compile
  • very occasionally, it introduces bugs
  • probably you want it on only for the final product

C, slide 13

Support Libraries

Another important skill for a C programmer is to find Another important skill for a C programmer is to find

off-the-shelf libraries that support what you want to do

off-the-shelf libraries that support what you want to do

One example is the Hans Boehm garbage collector One example is the Hans Boehm garbage collector

  • It replaces It replaces malloc() malloc() and automatically reclaims and automatically reclaims

garbage without having to use

garbage without having to use free()

free()

This helps you to program confidently with a high

This helps you to program confidently with a high

turnover of small objects, as in OO languages, without turnover of small objects, as in OO languages, without

worrying too much about memory leaks worrying too much about memory leaks

Memory leaks can still creep in, as with memory

Memory leaks can still creep in, as with memory

managed languages like Java, because of stale pointers

managed languages like Java, because of stale pointers

C, slide 14

Clean C

The rest of this chapter is about how to write clean The rest of this chapter is about how to write clean

object-oriented-style code in C (

object-oriented-style code in C ( before

before looking at C++)

looking at C++)

It is OK to use dirty tricks in C; you wouldn't be using It is OK to use dirty tricks in C; you wouldn't be using

C if you didn't have a good reason to use its dirty tricks C if you didn't have a good reason to use its dirty tricks

to gain speed or direct control of hardware or whatever to gain speed or direct control of hardware or whatever

But, it is also important to wrap up those dirty tricks in But, it is also important to wrap up those dirty tricks in

modules with clean interfaces modules with clean interfaces

It is this carefully controlled compromise between dirty

It is this carefully controlled compromise between dirty

and clean which makes a really good C programmer

and clean which makes a really good C programmer

For some reason, the books and web pages don't tell For some reason, the books and web pages don't tell

you how to write good, clean, object oriented C

you how to write good, clean, object oriented C

C, slide 16

Good Use of #define

  • One common use of One common use of #define #define is to give names to is to give names to

constants, e.g. constants, e.g.

#define TableSize 100

This is good because

This is good because

  • it makes the code more readable (no 'magic numbers')
  • it is more maintainable (one place to change it)
  • there is no efficiency penalty (textual replacement)

At first sight, it is attractive to use

At first sight, it is attractive to use #define

#define also for

also for

functions ('macros'), providing a simple way of gaining functions ('macros'), providing a simple way of gaining

speed by avoiding actual calls speed by avoiding actual calls

C, slide 17

The macro story

But, macros are deceptively dangerous, because textual But, macros are deceptively dangerous, because textual

substitution pays no attention to meaning, e.g.

substitution pays no attention to meaning, e.g.

#define plus1(n) n+

2plus1(3) --> 23+1 WRONG!**

This disaster leads to the first rule of macros:

This disaster leads to the first rule of macros:

Put brackets round the entire replacement text: Put brackets round the entire replacement text:

#define plus1(n) (n+1)

C, slide 19

The macro story 3

Try again: Try again:

#define max(m,n) ((m)>(n)?(m):(n))

max(2,in()) --> (2>in()? 2 : in())

WRONG!

  • The The in() in() function is called twice, instead of once function is called twice, instead of once

This new disaster can't be fixed, and leads to the third This new disaster can't be fixed, and leads to the third

and fourth rules of macros:

and fourth rules of macros:

Where an argument variable has to appear twice in Where an argument variable has to appear twice in

the replacement text, don't use macros at all the replacement text, don't use macros at all

When using standard macros, don't pass arguments

When using standard macros, don't pass arguments

which have side effects which have side effects

C, slide 20

The macro story 4

  • If you can't use a macro to speed up If you can't use a macro to speed up max max , what to do? , what to do?

Use inlining, starting with a static definition, like this: Use inlining, starting with a static definition, like this:

inline static int max(int m, int n)

{ return m>n? m : n; }

The inline keyword tells gcc to try to inline calls to The inline keyword tells gcc to try to inline calls to

max, and the static keyword means that max is local to max, and the static keyword means that max is local to

this file (i.e. private) so that gcc doesn't make a non-

this file (i.e. private) so that gcc doesn't make a non-

inlined global version for linking

inlined global version for linking

The gcc compiler is not capable of optimizing across The gcc compiler is not capable of optimizing across

modules, so how do we share an inlined function

modules, so how do we share an inlined function

across modules?

across modules?