Bob
Bob

Reputation: 735

C array: setting element at offset

I have a 2D array declared as

static bool array[ROW][COL];

Instead of using the indices, for a particular function I want to use a byte offset to set some of the elements, since the bools in this array are pretty much guaranteed to be 1 byte each.

loff_t *offset = 0;

So I try the following line.

array + *offset = false;

However, it compiles with the warning "lvalue required as left operand of assignment". What's wrong with this implementation, and how can I set the element of an array based on byte offset?

Upvotes: 1

Views: 1932

Answers (3)

HolyBlackCat
HolyBlackCat

Reputation: 96166

Instead of specifying byte offset directly by messing around with pointers while trying to avoid undefined behavior, you could just manually compute the indices for a specific offset:

array[offset / COL][offset % COL] = ...

Above will work only if sizeof (bool) == sizeof (char).

If your program already makes such assumption, you should add following:

static_assert(sizeof (bool) == sizeof (char), "sizeof bool != sizeof char");

If not, you should use different (pointer based) approach.

Upvotes: 3

AnT stands with Russia
AnT stands with Russia

Reputation: 320461

Setting a bool value stored in the array array at byte offset *offset will look as follows

*(bool *) ((char *) array + *offset) = true;

Of course, you will have to assume all risks that follow from this kind of access, since technques like this can easily run afoul of strict-aliasing rules. A safer alternative might be

bool new_value = true;
memcpy((char *) array + *offset, &new_value, sizeof new_value);

Upvotes: 0

chqrlie
chqrlie

Reputation: 144740

You can use an offset into the 2D array as if it were a 1D array, but it is not strictly correct as you are indexing beyond the subarray boundary:

*(array[0] + *offset) = false;         // not strictly correct

For this syntax, offset must contain a number of bool types, computed like this:

*offset = &array[row][col] - array[0];

or equivalently: *offset = &array[row][col] - &array[0][0];

An alternative is to alias with a character type, but bool might be larger than char, so this would be incorrect too:

*((char*)array + *offset) = false;  // potentially incorrect

To handle the case of bool larger than char, we may use:

*(bool *)((char*)array + *offset) = false;  // quite ugly

And offset should be computed this way:

*offset = (char*)&array[row][col] - (char*)array;

Upvotes: 2

Related Questions