static
within a file
will not interfere with identifiers outside that scope.
Thus, the following example will print 3 and not 7.
int i = 3;
foo()
{
int i = 7;
}
main()
{
foo();
printf("%d\n", i);
}
In addition, C also partitions a program's identifiers into four namespaces. Identifiers in one namespace, are also considered different from identifiers in another. The four namespaces are:
struct/union/enum
struct/union
(actually a separate namespace is assigned
to each struct/union
)
id
identifier instances are
different:
/* structure tag */
struct id {
int id; /* structure member */
};
/* Different structure */
struct id2 {
char id; /* structure member */
};
/* ordinary identifier */
id()
{
id: /* label */
}
Normally when you want to locate or change an identifier name, you only consider identifiers in the same scope and namespace. Sometimes however, a C preprocessor macro can semantically unite identifiers living in different namespaces, so that changes in one of them should be propagated to the others. The most common case involves macros that access structure members.
struct s1 {
int id;
} a;
struct s2 {
char id;
} b;
#define getid(x) ((x)->id)
main()
{
printf("%d %c", getid(a), getid(b));
}
id
instances should be propagated to all others for the program to
retain its original meaning.
CScout understands such changes and will propagate any changes
you specify accordingly.
Finally, the C preprocessor's token concatenation feature can result in identifiers that should be treated for substitution purposes in separate parts. Consider the following example:
int xleft, xright;
int ytop, ybottom;
#define coord(a, b) (a ## b)
main()
{
printf("%d %d %d %d\n",
coord(x, left),
coord(x, right),
coord(y, top),
coord(y, bottom));
}
x
in one of the coord
macro invocations should replace the x
part in the
xleft
and xright
variables.
Again CScout will recognize and correctly handle this code.