Felix Crazzolara
Felix Crazzolara

Reputation: 732

Arrays - Why is the subscript operator tied to the identifier?

Why is the subscript operator of an array tied to the identifier?

Cuz when we write:

int a[5];

a is actually of type "int[5]"

This prohibits to make use of the following:

typedef int[3][3] matrix_t;
....
void foo(matrix_t my_matrix){
  ....
}

What's the benefit of the actual implementation?

I really would like to have this feature or did I miss something?

Upvotes: 0

Views: 114

Answers (2)

AnT stands with Russia
AnT stands with Russia

Reputation: 320531

It is just a historical legacy from the early ages of C language development. Back then it was decided that declaration of an entity should mimic its future usage. So, array declarations look similar to the way arrays are used in expressions. The same applies to function declarations, pointer declarations etc. (* in pointer declaration is also "tied to the identifier")

In modern C++ in some contexts you can actually use the new syntax, which follows the logic you suggested. It applies to using-declarations for typename aliases (similar to classic typedef-declaration)

using array_type = int[3];
// Same as
// typedef int array_type[3];

or contexts like function return type declarations

auto foo() -> int (*)[3]
{
  ...

// Same as
// int (*foo())[3]

Upvotes: 1

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275415

In C, you type variables in the way you'd use them.

They are sort of like "frozen expressions".

So

int x[5][2];

means you'd use x by passing it first a value up to 5 in [], then a value up to 2 in [], and what you assign that value to is an int.

In a sense, this reuses the expression-parsing engine to type things.

typedef works like declaring a variable, except whatever the variable would be becomes an alias for that type. So instead of

typedef int[3][3] matrix_t;

it is

typedef int matrix_t[3][3];

again, this reuses the variable declaration parsing/grammar for defining type aliases.

In C++11, we have using that works more like you might want:

using matrix_t = int[3][3];

A final part of your problem is that matrices in C cannot be copied or passed by value. int[3][3] types as function parameters become int[3]* types -- pointers to int[3]s. And you cannot return an int[3][3] type period.

In C++, this is fixed via std::array:

std::array< std::array< int, 3 >, 3 >

is a type that is layout compatible with int[3][3] (at least in practice), but can be passed around like a value even to/from functions. In C you'd do:

struct matrix {
  int data[3][3];
};

which has the same layout in memory as the above std::array, and can be passed to/from functions like a value.

Upvotes: 3

Related Questions