G
Giacomo Catenazzi
Hello,
To learn the details of C, I've build the following example,
could you check if it is correct and if it miss some important
cases?
Are there some useful (real cases) examples of:
- "function prototype scope" for structures and unions?
- "extern" for internal linkage ?
ciao
cate
-------------------------
/* Scope, linkage and storage duration in C
* by Giacomo Catenazzi <[email protected]>
*/
/***************************************
* scope, linkage and storage duration *
***************************************/
/* Kind of identifier [C99:TC3 6.2.1]:
* - objects
* - functions
* - tags or members of a structure, union, or enumeration
* - typedef names
* - label names
* - macro name
* - macro parameter
*
* scope of identifiers [C99:TC3 6.2.1] (where the symbol is visible):
* - file scope,
* - function scope (only for labels),
* - block scope,
* - function prototype scope
*
* linkage (whenether two symbols are the same) [C99:TC3 6.2.2]:
* - external: across translation unit
* - internal (static): within translation unit
* - none: unique
*
* storage duration (lifetime of an object) [C99:TC3 6.2.4]:
* - static storage duration (it exists before to start up the program)
* - automatic storage duration
* - allocated storage duration
*/
/* objects scope linkage duration
* ******* ---------------------------*/
/* Note: here the same identifier name define the same entity */
int i; // i: file external static
extern int ei; // ei: file external static
static int si; // si: file internal static
extern int si; // si: file internal static //re-declaration
const int ci; // ci: file external static
extern const int eci; //eci: file external static
static const int sci; //sci: file internal static
int x1
(int j) { // j: block none automatic
int k; // k: block none automatic
static int sk; // sk: block none static
extern int ek; // ek: block external static
extern int i; // i: block external static //re-declaration
extern int ei; // ei: block external static //re-declaration
extern int si; // si: block internal static //re-declaration
return j+k+ek;
}
int x2
(int l); // l: fproto none automatic
/* functions scope linkage
* ********* ---------------*/
/* Note: same identifier name is the same function */
int f(int); // f: file external
extern int ef(int); // ef: file external
static int sf(int); // ef: file internal
int x2(int j) {
int g(int);// g: block external
extern int eg(int);// eg: block external
extern int ef(int);// ef: block external //re-declaration
extern int f(int);// f: block external //re-declaration
int ef(int);// ef: block external //re-declaration
int sf(int);// ef: block internal //re-declaration
return eg(j)+f(j);
}
/* tags scope linkage
* **** ---------------*/
struct t1 { // t1: file none
struct t2 { // t2: file none
int y1;
} y2;
} y3;
void x3(
struct t3 { // t3: block none
struct t4 { // t4: block none
int y4;}
y5;} y6) {
struct t5 { // t5: block none
struct t6 { // t6: block none
int y7;}
y8;
} y9;
struct t3 y10;
}
void x4(
struct t7 { // t7: fproto none
struct t8 { // t8: fproto none
int y11;}
y12;} y13);
struct t9 { // t9: block none
struct t10 { // t10: block none
int y12;}
y13;}
x5 (struct t9 y14) {
struct t9 y15;
}
struct t11 { // t11: fproto none
struct t12 { // t12: fproto none
int y16;}
y17;}
x6 (struct t11 y18) {
struct t11 y15;
}
/* note: tag could be declared more that once, but it is not
* considered as "linkage" */
struct t13;
struct t13* y19; /* note: this is not a declaration */
struct t13 {
int y20;
};
struct t13 y21; /* note: this is not a declaration */
/* labels scope linkage
* ****** ---------------*/
void x7(void) {
goto lab;
lab: ; // lab: function none
}
/* note: label is the only identifier with function scope,
* and it can be used before the definition. */
/* macro name and macro parameter
* ******************************/
/* the macro are defined and expanded in earlier phases,
* with different scope rules (e.g. macro can be undefined)
*/
To learn the details of C, I've build the following example,
could you check if it is correct and if it miss some important
cases?
Are there some useful (real cases) examples of:
- "function prototype scope" for structures and unions?
- "extern" for internal linkage ?
ciao
cate
-------------------------
/* Scope, linkage and storage duration in C
* by Giacomo Catenazzi <[email protected]>
*/
/***************************************
* scope, linkage and storage duration *
***************************************/
/* Kind of identifier [C99:TC3 6.2.1]:
* - objects
* - functions
* - tags or members of a structure, union, or enumeration
* - typedef names
* - label names
* - macro name
* - macro parameter
*
* scope of identifiers [C99:TC3 6.2.1] (where the symbol is visible):
* - file scope,
* - function scope (only for labels),
* - block scope,
* - function prototype scope
*
* linkage (whenether two symbols are the same) [C99:TC3 6.2.2]:
* - external: across translation unit
* - internal (static): within translation unit
* - none: unique
*
* storage duration (lifetime of an object) [C99:TC3 6.2.4]:
* - static storage duration (it exists before to start up the program)
* - automatic storage duration
* - allocated storage duration
*/
/* objects scope linkage duration
* ******* ---------------------------*/
/* Note: here the same identifier name define the same entity */
int i; // i: file external static
extern int ei; // ei: file external static
static int si; // si: file internal static
extern int si; // si: file internal static //re-declaration
const int ci; // ci: file external static
extern const int eci; //eci: file external static
static const int sci; //sci: file internal static
int x1
(int j) { // j: block none automatic
int k; // k: block none automatic
static int sk; // sk: block none static
extern int ek; // ek: block external static
extern int i; // i: block external static //re-declaration
extern int ei; // ei: block external static //re-declaration
extern int si; // si: block internal static //re-declaration
return j+k+ek;
}
int x2
(int l); // l: fproto none automatic
/* functions scope linkage
* ********* ---------------*/
/* Note: same identifier name is the same function */
int f(int); // f: file external
extern int ef(int); // ef: file external
static int sf(int); // ef: file internal
int x2(int j) {
int g(int);// g: block external
extern int eg(int);// eg: block external
extern int ef(int);// ef: block external //re-declaration
extern int f(int);// f: block external //re-declaration
int ef(int);// ef: block external //re-declaration
int sf(int);// ef: block internal //re-declaration
return eg(j)+f(j);
}
/* tags scope linkage
* **** ---------------*/
struct t1 { // t1: file none
struct t2 { // t2: file none
int y1;
} y2;
} y3;
void x3(
struct t3 { // t3: block none
struct t4 { // t4: block none
int y4;}
y5;} y6) {
struct t5 { // t5: block none
struct t6 { // t6: block none
int y7;}
y8;
} y9;
struct t3 y10;
}
void x4(
struct t7 { // t7: fproto none
struct t8 { // t8: fproto none
int y11;}
y12;} y13);
struct t9 { // t9: block none
struct t10 { // t10: block none
int y12;}
y13;}
x5 (struct t9 y14) {
struct t9 y15;
}
struct t11 { // t11: fproto none
struct t12 { // t12: fproto none
int y16;}
y17;}
x6 (struct t11 y18) {
struct t11 y15;
}
/* note: tag could be declared more that once, but it is not
* considered as "linkage" */
struct t13;
struct t13* y19; /* note: this is not a declaration */
struct t13 {
int y20;
};
struct t13 y21; /* note: this is not a declaration */
/* labels scope linkage
* ****** ---------------*/
void x7(void) {
goto lab;
lab: ; // lab: function none
}
/* note: label is the only identifier with function scope,
* and it can be used before the definition. */
/* macro name and macro parameter
* ******************************/
/* the macro are defined and expanded in earlier phases,
* with different scope rules (e.g. macro can be undefined)
*/