"Operator" square brackets [] when creating the arrangement in C

Asked

Viewed 595 times

7

Whenever I look for what the operator clasps [] makes, even in the tables that show all operators in C, appears that it serves to access an element of an arrangement. However, it is not always that this happens, as for example in the case where the arrangement does not yet exist, ie at the time of creation:

int main()
{
    // nessa linha, eu tenho a certeza de que o colchetes não faz acesso a nada.
    void *ptrArray[100];

    // porém, nessa linha, eu sei que o colchetes faz o acesso ao 2º elemento do arranjo
    ptrArray[1];
}

So, since it’s not mentioned anywhere about the operator [] when creating arrangements, I assume he is not an operator in this case. That’s right?

How does the compiler make this differentiation? I believe the compiler recognizes the difference because he saw that there was a keyword of a primitive kind or struct before, in my case is the key word void.

The return of the operator [] is always a pointer, right? So at compilation time, it’s like void *ptrArray[100] were void **ptrArray, right?

2 answers

7


In this case it is not an operator, it is an identical syntax with different semantics. On this line it is not operating anything, it is only declaring.

The compiler differentiates by the context it is in. When it appears in what we call lvalue is always the declaration form. When it appears in woodland is the operator.

Lvalue there is the statement itself, in that context is what comes before the =, and the woodland is an expression that can be used in several places in the code. This does not mean that it can be used in all `lvalue*. In fact it needs to be in a statement, this is already a semantic evaluation, it is another step of the compilation. If you want to know more: How is a compiler made?.

Obviously this is a simplification, the exact rule is much more complicated and can vary from compiler to compiler, as long as it complies with everything the specification says.

[] is always a way to access an address by a pointer. And void *ptrArray[100] is like a statement of void **ptrArray, but it’s not the same thing. See more on Arrays are pointers?. Has several links about that.

5

I’ll use the latest draft N2176 (that I found here: http://www.iso-9899.info/wiki/The_Standard) of C standardization to respond.

In the section [6.7.6], one of the parts of the syntax of a declarator is the direct statement (or direct-declarator), which is where the syntax for the arrangement statement is. What interests us here is the array (array declarator): given a statement T D1, if D1 is in one of the following forms:

D [ type-Qualifier-listopt assignment-Expressionopt ]

D [ type-Qualifier-listopt assignment-Expression ]

D [ type-Qualifier-list Static assignment-Expression ]

D [ type-Qualifier-listopt ]

So we have an array declarator. Note that the brackets are only used to indicate an array declarator, nothing else. There is no underwritten operation1 occurring here. For example, in the int a[8], the part a[8] is an arrangement declarator, where 8 is the size of the arrangement (or amount of elements).

If we are not in the context of statement and find an expression in the form I[N], where I has already been declared an arrangement (or pointer) so we certainly have the underwriting operation taking place. For example:

int a[8]; // Declara `a` como um arranjo de 8 elementos de tipo `int`.
a[0]; // Acessa o primeiro elemento de `a`, retornando um valor do tipo `int`.

Finally, on his last question regarding the equivalence between arrangements and pointers: arrangements can decay to pointers. Elaborating: in the declaration int a[8], the identifier a was declared to have the type int[8]. However, the expression a may well result in a value whose type is a pointer.

void foo(int *);

int main()
{
    int a[8]; // Declara `a` tendo tipo `int[8]`.

    foo(a); // O valor que a expressão `a` em si gera terá o
            // tipo decaído para um `int *`.
}

This decay behavior is described in the section [6.3.2/3]:

Except when it is the operand of the sizeof Operator, or the unary & Operator, or is a string literal used to initialize an array, an Expression that has type "array of type" is converted to an Expression with type "Pointer to type" that points to the initial element of the Object array and is not an lvalue. [...]


1 Subscribed is the name of the transaction access to elements of an arrangement.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.