C Programming Separate Compilation Variable Lifetime and Scope make.

30
C Programming Separate Compilation Separate Compilation Variable Lifetime and Scope Variable Lifetime and Scope make make

Transcript of C Programming Separate Compilation Variable Lifetime and Scope make.

Page 1: C Programming Separate Compilation Variable Lifetime and Scope make.

C Programming

Separate CompilationSeparate Compilation

Variable Lifetime and ScopeVariable Lifetime and Scope

makemake

Page 2: C Programming Separate Compilation Variable Lifetime and Scope make.

A Simple C Program/* sample.c */#include <stdio.h>typedef double Radius;#define PI 3.1415

/* given the radius, calculates the area of a circle */double circleArea( Radius radius ){

return ( PI * radius * radius );}

// given the radius, calcs the circumference of a circledouble calcCircumference( Radius radius ){

return (2 * PI * radius );}

int main( ){

Radius radius = 4.5;double area = circleArea( radius );double circumference = calcCircumference( radius );

printf (“Area = %10.2f, Circumference = %10.2f\n”, area, circumference);return 0;

}

Page 3: C Programming Separate Compilation Variable Lifetime and Scope make.

Reusable Functions

• The functions circleArea( ) and calcCircumference( ) The functions circleArea( ) and calcCircumference( ) are general functions that may be used by multiple are general functions that may be used by multiple applications.applications.

• To make them available to multiple applications To make them available to multiple applications without duplicating the code we must place them without duplicating the code we must place them into a separate .c file.into a separate .c file.

• However, recall that the compiler requires that we However, recall that the compiler requires that we must provide the function prototypes to the calling must provide the function prototypes to the calling code. We do this by placing the prototypes and code. We do this by placing the prototypes and supporting declarations into a header (.h) file which supporting declarations into a header (.h) file which is then included in .c files that wish to call the is then included in .c files that wish to call the functions.functions.

Page 4: C Programming Separate Compilation Variable Lifetime and Scope make.

circleUtils.h• A header (.h) file is the public interface (function A header (.h) file is the public interface (function

prototypes) for its corresponding .c file.prototypes) for its corresponding .c file.• It contains all definitions required by the prototypes It contains all definitions required by the prototypes

so that a .c file that includes it compilesso that a .c file that includes it compiles

/* circleUtils.h*/

// #includes required by the prototypes, if any

/* supporting typedefs and #defines required by the prototypes */typedef double Radius;

/* function prototypes */// given the radius, returns the area of a circledouble circleArea( Radius radius );

// given the radius, calcs the circumference of a circledouble calcCircumference( Radius radius );

Page 5: C Programming Separate Compilation Variable Lifetime and Scope make.

circleUtils.c/* circleUtils.c** Utilites for circle calculations*/#include “circleUtils.h”#define PI 3.1415 // why not in the .h file??

/* given the radius, calculates the area of a circle */double circleArea( Radius radius ){

return ( PI * radius * radius );}

// given the radius, calcs the circumference of a circledouble calcCircumference( Radius radius ){

return (2 * PI * radius );}

Page 6: C Programming Separate Compilation Variable Lifetime and Scope make.

Sample Code Revisited/* sample.c */#include <stdio.h>#include “circleUtils.h”

int main( ){

Radius radius = 4.5;double area = circleArea( radius );double circumference = calcCircumference( radius );

printf (“Area = %lf, Circumference = %lf\n”,area, circumference);

return 0;}

Page 7: C Programming Separate Compilation Variable Lifetime and Scope make.

Header Files• When a file contains functions to be reused in several When a file contains functions to be reused in several

programs, their prototypes and important programs, their prototypes and important #defines and and typedefs are placed into a header ( are placed into a header ( .h ) that is then ) that is then included where needed.included where needed.

• Each Each .h file should be “stand alone”. That is, it should file should be “stand alone”. That is, it should declare any declare any #define and and typedef needed by the needed by the prototypes and prototypes and #include any any .h files it needs to avoid files it needs to avoid compiler errors. The compiler errors. The .h file should contain everything file should contain everything needed to successfully compile any needed to successfully compile any .c file that includes it. file that includes it.

• In this example, the prototypes for In this example, the prototypes for circleArea() andand calcCircumference( ) are placed into the file are placed into the file circleUtils.h which would then be included in which would then be included in circleUtils.c and any other and any other .c file that uses file that uses circleArea( ) and / or and / or calcCircumference( )..

Page 8: C Programming Separate Compilation Variable Lifetime and Scope make.

Guarding Header Files

• Because a Because a .h file may include other file may include other .h files, there is files, there is the possibility that one or more the possibility that one or more .h files may files may unintentionally be included in a single unintentionally be included in a single .c file more file more than once, leading to compiler errors (multiple name than once, leading to compiler errors (multiple name definitions).definitions).

• To avoid these errors, To avoid these errors, .h files should be “guarded” files should be “guarded” using the compiler directivesusing the compiler directives #ifndef (read as “if (read as “if not defined”) and not defined”) and #endif

Page 9: C Programming Separate Compilation Variable Lifetime and Scope make.

Guarded circleUtils.h#ifndef CIRCLEUTIL_H#define CIRCLEUTIL_H

/* circleUtils.h */

/* #include .h files as necessary */

/* supporting typedefs and #defines */typedef double Radius;

/* function prototypes */// given the radius, returns the area of a circledouble circleArea( Radius radius );

// given the radius, calcs the circumference of a circledouble calcCircumference( Radius radius );

#endif

Page 10: C Programming Separate Compilation Variable Lifetime and Scope make.

1/20/10

Compiling and linking• When a program’s code is separated into multiple When a program’s code is separated into multiple .c files, we must compile each files, we must compile each .c file and then file and then link the resulting link the resulting .o files to create an executable files to create an executable program.program.

• The files may be compiled separately and then linked The files may be compiled separately and then linked together. The together. The -c flag in the first two command tells flag in the first two command tells gcc to to “compile only” which results in the creation of “compile only” which results in the creation of .o (object) (object) files. In the 3files. In the 3rdrd command, the presence of the command, the presence of the.o extension extension tells tells gcc to link the files into an executable to link the files into an executable

gcc -c -Wall circleUtils.cgcc -c -Wall sample.cgcc -Wall -o sample sample.o circleutils.o

• Or if there only a few files, compiling and linking can be Or if there only a few files, compiling and linking can be done all in one stepdone all in one step– gcc -Wall -o sample sample.c circleUtils.c

Page 11: C Programming Separate Compilation Variable Lifetime and Scope make.

Compiler vs linker

• The compiler translates one .c file into a .o fileThe compiler translates one .c file into a .o file– Verifies that all functions are being called correctly– Verifies that all variables exist– Verifies language syntax

• The linker combines multiple .o files (and C libraries) The linker combines multiple .o files (and C libraries) to create an executableto create an executable– “Finds” functions called by one .c/.o file, but defined in another

• E.g. printf( ), scanf( )

– “Finds” global variables used by one .c/.o file, but defined in another (more on this soon)

• Both can be invoked with gcc (see previous lecture)Both can be invoked with gcc (see previous lecture)

Page 12: C Programming Separate Compilation Variable Lifetime and Scope make.

Linking with C libraries

• By default, the standard C library which includes printf, By default, the standard C library which includes printf, scanf and char and string functions is always linked scanf and char and string functions is always linked with your program.with your program.

• Other libraries such as the math library must be Other libraries such as the math library must be explicitly linked with your code.explicitly linked with your code.

• The names of the C libraries alll have the form The names of the C libraries alll have the form libxxx.a. The standard C library is . The standard C library is libc.a. The C . The C math library is math library is libm.a..

• Specify libraries to be linked using the Specify libraries to be linked using the -l flag and the flag and the xxx part of the library name. part of the library name.– E.g. to link the math library with your program, use

gcc -Wall -o sample sample.c circleUtils.c -lm

Page 13: C Programming Separate Compilation Variable Lifetime and Scope make.

Project Organization

• main( ) is generally defined in its own .c file and generally just main( ) is generally defined in its own .c file and generally just calls helper functions calls helper functions – E.g. project1.c

• Project-specific helper functions may be in the same .c file as Project-specific helper functions may be in the same .c file as main( )main( )• main( ) comes first• Helper function order that makes sense to you

• Reusable functions in their own .c fileReusable functions in their own .c file– Group related functions in the same file– E.g. circleUtils.c

• Prototypes, typedefs, #defines, etc. for reusable function in a .h Prototypes, typedefs, #defines, etc. for reusable function in a .h filefile– Same file root name as the .c file. E.g. circleUtils.h

Page 14: C Programming Separate Compilation Variable Lifetime and Scope make.

Variable Scope and Lifetime

• The The scopescope of a variable refers to that of a variable refers to that part of a program that may refer to the part of a program that may refer to the variable.variable.

• The The lifetimelifetime of a variable refers to the of a variable refers to the time in which a variable occupies a time in which a variable occupies a place in memoryplace in memory

• The scope and lifetime of a variable are The scope and lifetime of a variable are determined by how and where the determined by how and where the variable is definedvariable is defined

Page 15: C Programming Separate Compilation Variable Lifetime and Scope make.

static and extern

• The keyword The keyword staticstatic is used to is used to– Limit the scope of a function or global variable– Extend the lifetime of a variable

• The keyword The keyword externextern is used to is used to– Inform the compiler that a (global) variable is defined in a

different .c file

Page 16: C Programming Separate Compilation Variable Lifetime and Scope make.

Function Scope

• All functions not found in the .c file that calls them All functions not found in the .c file that calls them are considered external because standard C does are considered external because standard C does not allow nesting of function definitions.not allow nesting of function definitions.– So no “extern” declaration is needed– All functions may be called from any .c file in your

project unless they are also declared as static.– The linker will “find” external functions called from one

.c file but defined in a different .c file

• static functions may only be called from within the .c functions may only be called from within the .c file in which they are definedfile in which they are defined• Their scope is limited

Page 17: C Programming Separate Compilation Variable Lifetime and Scope make.

Local variables• Local variables are defined within the opening and variables are defined within the opening and

closing braces of a function, loop, if-statement, etc. closing braces of a function, loop, if-statement, etc. (a code “block”). Function parameters are (a code “block”). Function parameters are considered local variables in their function.considered local variables in their function.– Are usable only within the block in which they are

defined– Exist only during the execution of the block unless

also defined as static– Initialized variables are reinitialized each time the

block is executed (if not defined as static)– static local variables retain their values for the

duration of your program. When used in functions, they retain their values between calls to the function.

Page 18: C Programming Separate Compilation Variable Lifetime and Scope make.

Global Variables

• GlobalGlobal ( (externalexternal) variables are defined outside of any function, ) variables are defined outside of any function, typically near the top of a .c file.typically near the top of a .c file.– May be used anywhere in the .c file in which they are defined.– Exist for the duration of your program– May be used by any other .c file in your application that

declares them as “extern” unless also defined as static (see below)

– Static global variables may only be used in the .c file that declares them

– “extern” declarations for global variables should be placed into a header file

Page 19: C Programming Separate Compilation Variable Lifetime and Scope make.

randomInt.c/* a global variable to be used by code in other .c files.** This variable exists until the program ends** Other .c files must declare this variable as "extern“ */long randomInt;

/* a function that can be called from any other function** sets randomInt to a value from 1 to max, inclusive */void getRandomInt( int max ){

randomInt = getNext( );}

/* a function that can only be called from functions within this file */

static long getNext( ){ /* lastRandom is a local variable that can only be used

inside this function, but persists between calls to this function */

static long lastRandom = 100001;

lastRandom = (lastRandom * 125) % 2796203; return (lastRandom % max) + 1;}

Page 20: C Programming Separate Compilation Variable Lifetime and Scope make.

randomInt.h

#ifndef RANDOMINT_H

#define RANDOMINT_H

// global variable in randomint.c

extern int randomInt;

// prototypes for non-static (“public”)

// functions in randomInt.c

void getRandomInt( int max );

#endif

Page 21: C Programming Separate Compilation Variable Lifetime and Scope make.

variableScope.c - part 1#include <stdio.h>

// extern definition of randomInt and prototype for getRandomInt#include “randomInt.h”

/* a global variable that can only be used by functions in this .c file */static int inputValue;

/* a function that can only be called by other functions in this .c file */static void inputPositiveInt( char prompt[ ] ){ /* init to invalid value to enter while loop */ inputValue = -1; while (inputValue <= 0) { printf( "%s", prompt); scanf( "%d", &inputValue); }}

Page 22: C Programming Separate Compilation Variable Lifetime and Scope make.

variableScope.c - part 2/* main is the entry point for all programs */int main( ){ /* local/automatic variables that can only be used in this

function and that are destroyed when the function ends */ int i, maxValue, nrValues;

inputPositiveInt("Input max random value to generate: "); maxValue = inputValue;

inputPositiveInt("Input number of random ints to generate: "); nrValues = inputValue;

for (i = 0; i < nrValues; i++) { getRandomInt( maxValue ); printf( “%d: %d\n", i + 1, randomInt ); }

return 0;}

Page 23: C Programming Separate Compilation Variable Lifetime and Scope make.

The make Utility

Typing out the gcc commands for a project gets less appealing as the project gets bigger.

The "make" utility automates the process of compiling and linking.

With make, the programmer specifies what the files are in the project and how they fit together. make takes care of the appropriate compile and link steps.

make can speed up your compiles since it is smart enough to know that if you have 10 .c files but you have only changed one, then only that one file needs to be compiled before the link step.

make has some complex features, but using it for simple things is pretty easy.

This slide and those that follow are adapted from Section 2 of “UnixProgrammingTools.pdf” by Nick Parlante, et al at Stanford. Used with permission.

Page 24: C Programming Separate Compilation Variable Lifetime and Scope make.

How make works

• You tell You tell makemake what files are in your project, how they what files are in your project, how they fit together, how to compile, and how to link them by fit together, how to compile, and how to link them by creating a file that creating a file that makemake reads and interprets reads and interprets– By default, make looks for a file named either “makefile” or

“Makefile”

• At the Unix console, simply type the command At the Unix console, simply type the command makemake to compile all necessary files and create a new to compile all necessary files and create a new executableexecutableunix> make

• makemake can perform other tasks defined in the can perform other tasks defined in the makefilemakefile as well (more on this later) as well (more on this later)

Page 25: C Programming Separate Compilation Variable Lifetime and Scope make.

The makefile

• A makefile consists of variable definitions, A makefile consists of variable definitions, dependency/build rules and commentsdependency/build rules and comments

• Comments begin with the ‘#’ character and extend to Comments begin with the ‘#’ character and extend to the end of the linethe end of the line# makefile for project 1

# name, date, etc

Page 26: C Programming Separate Compilation Variable Lifetime and Scope make.

The makefile (2)• Variable definitionsVariable definitions

– A variable name is defined to represent a string of text, similar to #define in C. They are most often used to represent names of files, directories, and the compiler.

– Variable are defined simply by setting them to some value (string)– The most common variables are typically

• CC -- the name of your C compiler• CFLAGS -- the set of flags that you wish to pass to the compiler• LDFLAGS -- the set of flags that you wish to pass to the linker• OBJS -- the set of object (.o) files that are linked together to create your

executable

• To use a variable, use the dollar sign ($) followed by the name of To use a variable, use the dollar sign ($) followed by the name of the variable in parenthesis or curly bracesthe variable in parenthesis or curly bracesCC = /usr/local/bin/gccCFLAGS = -g -Wall$(CC) $(CFLAGS) -c main.c

• Variables that are not initialized are set to the empty stringVariables that are not initialized are set to the empty string

Page 27: C Programming Separate Compilation Variable Lifetime and Scope make.

The make file (3)

• A dependency/build rule defines how to make a A dependency/build rule defines how to make a target based on changes to the files on which the target based on changes to the files on which the target depends.target depends.

• The order of the rules is irrelevant, except that the The order of the rules is irrelevant, except that the first rule is the default rule -- the rule that will be first rule is the default rule -- the rule that will be used when used when make is executed with no arguments is executed with no arguments

• A dependency/build rule is made up of two partsA dependency/build rule is made up of two parts– A dependency line followed by one or more command lines

Page 28: C Programming Separate Compilation Variable Lifetime and Scope make.

The make file (4)

• Example dependency/build ruleExample dependency/build rulesample.o : sample.c circleUtils.h

<TAB> $(CC) $(CFLAGS) -c sample.c

• The first (dependency) line of this rule says that The first (dependency) line of this rule says that sample.o must be must be rebuilt whenever rebuilt whenever sample.c or or circleUtils.h changes. Generally a .o file changes. Generally a .o file depends on its own .c file and any non-library .h files it depends on its own .c file and any non-library .h files it #includes. In . In this example, we would expect that sthis example, we would expect that sample.c #includes circleUtils.h

• The second (command) line tells make how to rebuild sample.oThe second (command) line tells make how to rebuild sample.o– Gotcha -- the command line MUST be indented with a TAB character. Spaces

won’t do. This can be a problem when cutting/pasting the contents of a makefile from a terminal screen. Some editors will automatically change a TAB into spaces.

Page 29: C Programming Separate Compilation Variable Lifetime and Scope make.

Sample makefile

See See /afs/umbc.edu/users/c/m/cmsc313/pub/code/makefile/afs/umbc.edu/users/c/m/cmsc313/pub/code/makefile

Page 30: C Programming Separate Compilation Variable Lifetime and Scope make.

make features

• The The make utility has some built-in default rules. utility has some built-in default rules.• In particular, the default rule for C files isIn particular, the default rule for C files is

$(CC) $(CFLAGS) -c source-file.c$(CC) $(CFLAGS) -c source-file.c

• Special syntax canSpecial syntax can be used to create the list of be used to create the list of the .o filesthe .o filesOBJS = $(SRCS: .c=.o)OBJS = $(SRCS: .c=.o)