8. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Directivele #define si #undef
,
Directivele de preprocesare ˆ
ıncep cu #
Definirea si anularea definirii
,
#define MY VAR 50
#undef MY VAR
a = a + MY VAR → a = a + 50
8 / 41
9. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri simple (object-like macros)
#define NUME VALOARE
NUME respect˘ regulie de nume pentru o variabil˘
a a
VALOARE poate s˘ contin˘ aproape orice
a , a
Se ˆ
ınlocuieste NUME cu VALOARE peste tot
,
9 / 41
10. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Stupid example
1 # 1 "stupid example.c"
2 # 1 "<built-in>"
1 #define begin {
3 # 1 "<command-line>"
2 #define end }
4 # 1 "stupid example.c"
3 #define stop return 0
5
4
6
5 int main(void)
7
6 begin
8
7 printf("Hello,
9 int main(void)
World!n");
10 {
8
11 printf("Hello, World!n");
9 stop;
12
10 end
13 return 0;
14 }
10 / 41
11. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Folosirea parantezelor
O greseal˘ frecvent˘
, a a
Once upon a time during a PSO lab (2006-2007)
#define NR syscalls MY SYSCALL NO+1
...
new syscall table =
malloc(NR syscalls * sizeof(void *));
Nu faceti asa
, ,
#define MAX(a, b) (a > b ? a : b)
Faceti asa
, ,
#define MAX(a, b) ((a) > (b) ? (a) : (b)
E OK tot timpul?
11 / 41
12. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri vs. const
Avantaje macro-uri
mai rapide (faza de preprocesare)
interpretate la preprocesare
nu ocup˘ spatiu ˆ memorie
a , ın
Avantaje const
type safety
sunt, de fapt, variabile (au o adres˘)
a
ˆ C++ se pot folosi la preprocesare
ın
12 / 41
13. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri vs. enum
Avantaje macro-uri
flexibile (nu sunt limitate la valori ˆ
ıntregi)
nu impun constrˆngeri de spatiu ocupat
a ,
Avantaje enum
type safety
block scope
13 / 41
14. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri predefinite
$ gcc -dM -E sample.c
#define CHAR BIT 8
#define unix 1
#define x86 64 1
#define SHRT MAX 32767
#define linux 1
#define gnu linux 1
#define SAMPLE H 1
#define TEST NUM 25
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define STDC 1
$ gcc -dM -E sample.c | wc -l
131
14 / 41
15. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Definirea de macro-uri ˆ linia de comand˘
ın a
$ gcc -DMY MACRO=40 -Wall comm.c
$ ./a.out
MY MACRO = 40
$ gcc -dM -E code/sample.c | grep linux
#define linux 1
$ gcc -U linux -dM -E code/sample.c | grep linux
$
15 / 41
16. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri cu parametri (function-like macros)
#define echo() printf("Hello, World!n");
#define max(a, b) ((a) > (b) ? (a) : (b))
#define do error(msg)
perror(msg);
exit(EXIT FAILURE);
E ceva gresit?
,
if (error condition) do error();
16 / 41
17. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri cu parametri (cont.)
#define do error(msg) {
perror(msg);
exit(EXIT FAILURE);
}
Inconsistent˘ - nu e nevoie de ; (punct si virgul˘) la apel
,a , a
#define do error(msg) do {
perror(msg);
exit(EXIT FAILURE);
} while (0)
Perfect!
17 / 41
18. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri vs. functii inline
,
Avantaje functii inline
,
type safety
f˘r˘ b˘t˘i de cap
aa aa
Avantaje macro-uri
sunt portabile
unele lucruri se realizeaz˘ mai greu cu functii inline (argumente
a ,
transmise prin adres˘)a
unele lucruri nu se pot face cu functii inline
,
#define container of(ptr, type, member)
(type *)( (char *)ptr - offsetof(type,member))
18 / 41
19. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Macro-uri cu num˘r variabil de argumente (variadic
a
macros)
Similar functiilor cu num˘r variabil de argumente
, a
ˆ standardul C99
In
#define DEBUG(fmt, ...)
fprintf(stderr, fmt, VA ARGS );
O problem˘: apel DEBUG("problema");
a
Solutie: token paste operator (##) (extensie GNU)
,
#define DEBUG(fmt, ...)
fprintf(stderr, fmt, ## VA ARGS );
19 / 41
20. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Probleme ˆ folosirea macro-urilor
ın
Precedenta operatorilor
,
solutie: folosirea parantezelor
,
Omiterea operatorului ; (punct si virgul˘)
, a
solutie: folosirea do { ...
, } while(0)
Linii multiple
solutie: folosirea operatorului (backslash)
,
20 / 41
22. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Directive de preprocesare conditionat˘
, a
#if expresie conditionala
#if defined macro / #ifdef macro
#endif
#else
#elif
22 / 41
23. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Asigurarea portabilit˘tii
a,
1 #include <stdio.h>
2
3 int main (void)
4 {
5 #if defined ( linux )
6 printf ("This is Linux.n");
7 #elif defined ( win32 )
8 printf ("This is Win32.n");
9 #else
10 printf ("This is Sparta.n");
11 #endif
12
13 return 0;
14 }
23 / 41
24. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
“Eliminarea” codului
Util pentru “comentarii”
Trebuie s˘ contin˘ cod “preprocesabil”
a , a
#if 0
aaaa
/*
...
*/
if ...
for ...
...
#endif
24 / 41
25. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Activare/dezactivare mod debug
1 #ifndef DEBUG H
2 #define DEBUG H 1
3
4 #if defined DEBUG
5 #define Dprintf(format, ...)
6 fprintf(stderr, "[%s]:%s:%d: " format, FILE ,
7 func , LINE , ## VA ARGS )
8 #else
9 #define Dprintf(format, ...) do { } while(0)
10 #endif
11
12 #endif
Se poate defini un macro ˆ acelasi fisier header
ın , ,
Se poate folosi linia de comand˘ gcc -DDEBUG
a ...
Avansat, se pot stabili niveluri de jurnalizare (DEBUG LEVEL +
Dprintf info, Dprintf warn etc.)
25 / 41
26. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Combinare cod C si cod C++
,
Compilatorul de C++ face “name mangling”
Linker-ul nu recunoaste simbolurile
,
1 #ifndef MIX HEADER H
2 #define MIX HEADER H 1
3
4 #ifdef cplusplus
5 extern "C" {
6 #endif
7
8 void fun1(void);
9 void fun2(void);
10
11 #ifdef cplusplus
12 }
13 #endif
14
15 #endif
26 / 41
28. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Directiva #include
Permite inserarea unui fisier header
,
Se copiaz˘ continutul acelui fisier
a , ,
Poate fi (si de obicei este) folosit˘ pe mai multe niveluri (un
, a
fisier header include alte fisiere header)
, ,
28 / 41
29. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Exemplu de structur˘ de fisier header
a ,
#ifndef MY HEADER H
#define MY HEADER H 1
...
#endif
Macro-uri de gard˘/control
a
Previn includerea de mai multe ori a aceluiasi fisier
, ,
Denumite, ˆ general MY HEADER H, MY HEADER H (rezervate
ın
pentru biblioteca standard), MY HEADER H , MY HEADER H
29 / 41
30. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Ce contine un fisier header?
, ,
Macro de gard˘ (#ifndef ...)
a
Includerea altor fisiere header
,
se folosesc tipuri definite ˆ alt header
ın
se folosesc functii (vezi Dprintf)
,
Macro-uri
Structuri de date si enumer˘ri
, a
Declaratii externe de variabile
,
Declaratii (antete) de functii
, ,
Functii statice
,
Functii inline (de asemenea statice)
,
Sfˆrsit macro de gard˘ (#endif)
a , a
30 / 41
31. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
De ce nu se include un fisier C?
,
Un fisier C contine functii si variabile globale care pot fi
, , , ,
non-statice
Dac˘ acel fisier e inclus de dou˘ fisiere diferite care sunt
a , a ,
link-editate apare conflict de forma already defined
Un fisier header nu trebuie s˘ aib˘ forma unui fisier C
, a a ,
f˘r˘ variabile globale non-statice
aa
f˘r˘ functii non-statice
aa ,
31 / 41
32. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
#include <file.h> vs. #include ”file.h”
#include <file.h>
system headers
c˘utare ˆ
a ıntr-un set de directoare predefinite
localizate preponderent ˆ /usr/include si
ın ,
/usr/local/include
#include "file.h"
local headers
c˘utare ˆ
a ıncepˆnd cu directorul local
a
32 / 41
33. Notiuni generale
, Macrodefinitii
, Preprocesare conditionat˘
, a Includerea fisierelor header
, Altele Resurse utile
Extinderea c˘ii de c˘utare a fisierelor header
a a ,
CPPFLAGS = -I/usr/include/gdk/ -iquote../include
Forma #include <file.h> caut˘ ˆ ai ˆ directoarele
a ıntˆ ın
marcate cu -I si apoi ˆ cele implicite
, ın
Forma #include "file.h" caut˘ ˆ directoarele marcate cu
a ın
-iquote, apoi ˆ cele marcate cu -I, apoi ˆ directorul local
ın ın
si apoi ˆ cele implicite
, ın
33 / 41