Stas Jaro
Stas Jaro

Reputation: 4885

How to specify scope in C?

Is it possible to specify the scope in C?

int x = 5;

void setX(int x) {
    (this, self, etc).x = x;
}

I know that there cannot be a this or self in C because it is not an object. Is there any way to do this?

Upvotes: 2

Views: 148

Answers (4)

ouah
ouah

Reputation: 145829

Well in your example, you just cannot. The file scope object x is hidden by the block scope object x and you cannot access the file scope object x directly (i.e., I mean without using some pointers to the file scope x).

(C99, 6.2.1p4) "If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will be a strict subset of the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope."

EDIT: See @howardh answer, without using pointers it is possible to refer to the file scope object in the inner scope with use of the extern specifier.

From The New C Standard by Derek M. Jones:

"It is possible to refer to objects in disjoint scopes by using pointers to them. It is also possible, through use of linkage, for an identifier denoting an object at file scope to be visible within a nested block scope even though there is another declaration of the same identifier in an intervening scope."

extern int glob;

void f1(void)
{
    int glob = 0;
    {
        extern int glob; /* Refers to same object as file scope glob. */
        glob++;
    }
    /* Visible glob still has value 0 here. */
}

Upvotes: 3

Richard J. Ross III
Richard J. Ross III

Reputation: 55533

You could do it with some pointer-mangling & macros:

int x;

#define setX(val) _actualSetX(&x, val);

void _actualSetX(int *xPtr, int x)
{
    *xPtr = x;
}

Upvotes: 0

Niklas B.
Niklas B.

Reputation: 95278

The way this is usually done is to "emulate" OO by giving the function as an additional argument a pointer to some kind of context:

struct state {
  int x;
}

void setX(struct state *ctx, int x) {
  ctx->x = x;
}

/* later ... */
struct state ctx;
setX(&ctx, 5);

EDIT: I just realized that you rather want to force your compiler to explicitly assign to the global variable instead of the local argument. Well, this is not possible, but the above example shows how you could achieve something similar to what you're maybe used to from other programming languages. Even in C, using global variables is not necessarily a good idea.

Upvotes: 3

howard
howard

Reputation: 644

You can use extern to access the global variable like such:

int a = 10;

int foo(int a)
{
    int b;
    {
        extern int a;
        b = a;
    }
    //b now contains the value 10
}

Upvotes: 5

Related Questions