Advanced C Programming: Declarations, External Names, Memory Layout
Advanced C Programming: Declarations, External Names, Memory Layout
Sebastian Hack
[email protected]
Christoph Weidenbach
[email protected]
04.11.2008
saarland
university
computer science
1
Overview
Declarations
Properties of Declarations
Storage Classes
Type Qualifiers
Declarators
External Names
Linkage Models
C++ Compatibility
Memory Layout (Linux)
Literature
I Harbison & Steele, C — A Reference Manual, Chapter 4
I ISO/IEC 9899:1999, Chapter 6
I C Design Rationale, Chapter 6.2.2
See course website for links
2
Declarations
3
Structure of Declarations
A declaration in C consists of
I Storage class specifier: extern, static, auto, register
Convention
Use following order: storage class, qualifier, specifier
4
Attributes of Declarations
5
Visibility
I One declaration can hide another
int foo = 10;
int main ( void ) {
float foo ; /* this foo hides outer foo */
...
}
j == 0 or j == 10?
6
Visibility
I One declaration can hide another
int foo = 10;
int main ( void ) {
float foo ; /* this foo hides outer foo */
...
}
j == 0 or j == 10?
Rule
Scope starts at declaration point, not at start of enclosing block
6
Name Spaces
7
Name Spaces
7
Extent
I Local extent
I Created on entry to a block or function
I Destroyed at block’s (function’s) exit
I Re-created each time block/function is entered
8
Storage Classes
auto and register
9
Storage Classes
extern and static
extern
I Static extent
I External Linkage
I Variables: non-defining declaration:
no memory will be allocated for the variable
I Functions: Default for top-level defined functions
static
I Static extent
I Internal linkage
I Variables: tentative declaration:
If no initializer is given, then variable will be
initialized to 0
Attention!
Note that top-level defined variables without storage class are not
extern. They have external linkage, but that is not identical to extern
10
Type Qualifiers
const
I Helps you:
avoid unintentional write to data that should not be written to
I Helps the compiler:
Can optimize memory access because it knows that const variables
cannot be modified
I Pay attention to pointer rules:
int * const const_pointer ;
const int * p o i n t e r _ t o _ c o n s t ;
11
Type Qualifiers
const — Usage Example
I Use const for getters
struct coord {
int x , y ;
}
12
Type Qualifiers
const — Usage Example
I Use const for getters
struct coord {
int x , y ;
}
Rules
I Understand usage of const
I Use const where ever possible
I Never de-const-ify code
I Never cast const pointer to non-const pointer
12
Type Qualifiers
volatile
I Important for concurrency (software and hardware!)
I Usually, the compiler has some freedom where to store the contents
of variables
I Dependent on this storage location, concurrent updates might be
seen or not
I Example
14
Type Qualifiers
restrict (C99)
I Inside add, the compiler can assume that arrays a and b do not
overlap
I If they do, the behavior may be undefined
15
Declarators
Overview
I More examples:
int *(*(* fp1 )( int ))[10];
float (*(* b ())[])();
void *(* c )( char , int (*)());
...
16
Declarators
17
Initializations
Guidelines
I Separate declaration and initialization
I Multiple, comma-separated initializations are hard to read
I Avoid visibility problems (see earlier slides)
18
Implicit Declarations
I Usually, all identifiers have to be declared before they are used
I In C89 there is one exception that can lead to hard-to-find bugs
void f ( void ) {
g (2.718);
}
void g ( int x ) {
printf ( " % d \ n " , x );
}
is assumed
I Prototype does not describe the function but how it is called!
I Thus: Always provide correct prototype
19
External Names
I How to make objects visible/hidden to other translation units?
I Easy for functions:
I Give static for local linkage
I Give or omit extern for external linkage
I Whole program needs exactly one definition for a (used!) function in
one of the translation units
Major Question
Which declaration of a global-linkage variable creates storage?
+ There are four models (!) and the standard
20
External Names
Linkage Models
Common
I All declarations with external linkage (no matter if extern or not)
create storage.
I The linker puts all definitions of the same name to the same address
I Named after FORTRAN common zones
Relaxed Ref/Def
I Declarations with extern are pure references
+ no storage allocated
I Definitions are declarations without storage class
I In all translation units, at least one definition must exist
I Referencing declarations of unused vars may be ignored
Strict Ref/Def
I Like relaxed Ref/Def, but exactly one definition must exist
Initialization
I Only declarations that initialize the variable create storage
21
Linkage Models !"#$%"$&'
Overview (from C99 Design Rationale, Chapter 6.2.2)
'
*+$%,&'-./0'1234",+52#'26'+7+6+&,'9+#:"$&'327&95'
;27&9' *+9&'/' *+9&'<'
12332#' !"#!$%&'%#&'(& !"#!$%&'%#&'(&
'%#&)*'%+&,& 52'3&0!12%3+&,&
-& -&
&&&&'&.&/(& &&&'$3+&'&,(&
&&&&0!12%3+&,(& 4&
4&
=&9">&7'=&6?@&6' '%#&'(& '%#&'(&
'%#&)*'%+&,& 52'3&0!12%3+&,&
-& -&
&&&&'&.&/(& &&&'$3+&'&,(&
&&&&0!12%3+&,(& 4&
4&
A8,+B8'=&6?@&6' '%#&'(& !"#!$%&'%#&'(&
'%#&)*'%+&,& 52'3&0!12%3+&,&
-& -&
&&&&'&.&/(& &&&'$3+&'&,(&
&&&&0!12%3+&,(& 4&
4& &
C#+8+"9+D&,' '%#&'&.&7(& '%#&'(&
'%#&)*'%+&,& 52'3&0!12%3+&,&
-& -&
&&&&'&.&/(& &&&'$3+&'&,(&
&&&&0!12%3+&,(& 4&
4&
!"#"$% &'()%*+',)*%-.%/0)12/./)3*% 22
Linkage Models
The Standard
I Combination of strict Ref/Def and Initialization
I Only one file has definition
I Definition is declaration without storage class specifier or extern
with initializer
I Having multiple definitions causes undefined behavior!
(does not mean that you get an error message!)
23
Linkage Models
The Standard
I Combination of strict Ref/Def and Initialization
I Only one file has definition
I Definition is declaration without storage class specifier or extern
with initializer
I Having multiple definitions causes undefined behavior!
(does not mean that you get an error message!)
Conclusion
I False assumption on linkage model can be source of bugs!
I gcc under Linux does not use the standard model, but the UNIX one
I Do not rely on that when you want to write portable code!
23
Linkage Models
The Standard
I Combination of strict Ref/Def and Initialization
I Only one file has definition
I Definition is declaration without storage class specifier or extern
with initializer
I Having multiple definitions causes undefined behavior!
(does not mean that you get an error message!)
Conclusion
I False assumption on linkage model can be source of bugs!
I gcc under Linux does not use the standard model, but the UNIX one
I Do not rely on that when you want to write portable code!
Guideline
I Use strict Ref/Def
I Exactly one file with definition (declaration without storage class)
I All other declarations use extern
23
C++ Compatibility
I Your C code might be used by a C++ project. Be prepared for that.
I Biggest issue: C++ mangles function names
extern int my_func ( double , const char *);
int main () {
return my_func (2.345 , " Hallo " );
}
I Initialized Data
I global/local linkage data that has been initialized
I can be set read-only for const variables
25
Memory Layout (Unix/Linux)
. . . cont’d
I Heap
I Dynamically allocated data (malloc)
I Usually grows upwards
I Stack
I auto variables
I stack frames
I spilled registers
I usually grows downwards
26
Memory Layout (Unix/Linux)
. . . cont’d
I Heap
I Dynamically allocated data (malloc)
I Usually grows upwards
I Stack
I auto variables
I stack frames
I spilled registers
I usually grows downwards
Homework
Write a small program that prints the addresses of the segments
26