Reputation: 1989
I defined structures in C like this:
struct cache_line{
char valid;
int tag;
int LRU;
};
struct cache_set{
struct cache_line *lines;
};
struct cache{
struct cache_set *sets;
};
After these structures definitions, I define a function:
void do_something(struct cache_set *a_cache_set, int number){
*a_cache_set.lines[next].tag = tag;
*a_cache_set.lines[next].LRU = *current_count;
*a_cache_set.lines[next].valid = 1;
}
In the main, I define a cache_set and do:
struct cache_set a_cache_set = my_cache.sets[setid];
int a_number = 10;
do_something(&a_cache_set, a_number);
However, when compiling, I get the following error at the do_something definition (at
*a_cache_set.lines[next].tag = tag;
*a_cache_set.lines[next].LRU = *current_count;
*a_cache_set.lines[next].valid = 1;
) :
error: request for member ‘lines’ in something not a structure or union
Yet, I explicitly declared a_cache_set as a cache set which contains lines...
What is wrong here?
Upvotes: 1
Views: 84
Reputation: 140445
The operator precedence rules for C say that
*a_cache_set.lines[next].tag = tag;
is interpreted the same as
*(a_cache_set.lines[next].tag) = tag;
so, you are applying the .
operator to a_cache_set
, and not *a_cache_set
as you probably expected. Same problem on the other two lines.
The preferred way to write this sort of thing in C is with the ->
operator:
a_cache_set->lines[next].tag = tag;
In fact, it could be said that unary *
being a lower-precedence prefix operator is why ->
exists. (Contrast, say, UCSD Pascal, where you would write a_cache_set^.lines
.)
Upvotes: 2
Reputation: 5856
Your code *a_cache_set.lines[next].tag = tag;
means the following:
lines
member from a struct or union referred to by a variable named a_cache_set
lines
tag
membertag
's value to that dereferenced resultAs it stands the very first operation in that list fails in your code as the variable a_cache_set
is a pointer which is not dereferenced yet.
The fix is (as suggested already in comments) to dereference using ->
operator
Upvotes: 2
Reputation: 206567
This is an operator precedence issue.
*a_cache_set.lines[next].tag = tag;
*a_cache_set.lines[next].LRU = *current_count;
*a_cache_set.lines[next].valid = 1;
is equivalent to
*(a_cache_set.lines[next].tag) = tag;
*(a_cache_set.lines[next].LRU) = *current_count;
*(a_cache_set.lines[next].valid) = 1;
What you need is:
(*a_cache_set).lines[next].tag = tag;
(*a_cache_set).lines[next].LRU = *current_count;
(*a_cache_set).lines[next].valid = 1;
or, better,
a_cache_set->lines[next].tag = tag;
a_cache_set->lines[next].LRU = *current_count;
a_cache_set->lines[next].valid = 1;
Upvotes: 6
Reputation: 75545
You are trying to use .
operator on a pointer. You have to use parenthesis to force dereference before .
, or use ->
operator instead.
(*a_cache_set).lines[next].tag = tag;
(*a_cache_set).lines[next].LRU = *current_count;
(*a_cache_set).lines[next].valid = 1;
Option B:
a_cache_set->lines[next].tag = tag;
a_cache_set->lines[next].LRU = *current_count;
a_cache_set->lines[next].valid = 1;
Upvotes: 4