what is the type for this call?

N

Neo

If i have a :
typedef struct str32{
uint32_t word1;
uint32_t word2;
} word_array;

word_array *my_array;

what would be the data type of this:
myarray->word1
How come it is a uint32_t type and is giving the value of word1? isn't
it still a pointer which is not dereferenced yet?
I was thinking I should have to do *(my_array->word1) to get to
uint32_t type, what goes?
 
C

Chris Dollin

Neo said:
If i have a :
typedef struct str32{
uint32_t word1;
uint32_t word2;
} word_array;

(Why are you calling the struct a "str32" and the type "word_array"?
Neither name seems appropriate and their relationship is tenuous.)
word_array *my_array;

what would be the data type of this:
myarray->word1

unint32_t.
How come it is a uint32_t type and is giving the value of word1?

You declared `word1` as a unint32_t, so that's what it is.
isn't it still a pointer which is not dereferenced yet?
No.

I was thinking I should have to do *(my_array->word1) to get to
uint32_t type, what goes?

`A->B` is `(*(A.B))`; the arrow has done the dereference for you.
 
A

abasili

Neo said:
If i have a :
typedef struct str32{
uint32_t word1;
uint32_t word2;
} word_array;

word_array *my_array;

what would be the data type of this:
myarray->word1
How come it is a uint32_t type and is giving the value of word1? isn't
it still a pointer which is not dereferenced yet?
I was thinking I should have to do *(my_array->word1) to get to
uint32_t type, what goes?

To my understanding either u use (*my_array).word1 or my_array->word1.
Parenthesis are need for precedence.
 
A

abasili

Chris said:
`A->B` is `(*(A.B))`; the arrow has done the dereference for you.

B is not a pointer, so I think your notation is wrong.
you should use (*A).B instead
 
C

Chris Dollin

abasili said:
B is not a pointer, so I think your notation is wrong.
you should use (*A).B instead

You are quite right; I fumbled my bracketing. (I wondered why I needed
the extra outer brackets ... should have wondered harder.)
 
N

Neo

You are quite right; I fumbled my bracketing. (I wondered why I needed
the extra outer brackets ... should have wondered harder.)

--
"We are on the brink of a new era, if only --" /The Beiderbeck Affair/

Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN

Oh my bad, so my c has gotten very rusty. Ok now if I do
my_array.word1 do I get a pointer to word1?
 
A

abasili

Neo said:
Oh my bad, so my c has gotten very rusty. Ok now if I do
my_array.word1 do I get a pointer to word1?

being my_array a pointer to a structure this syntax, to me, doesn't have
any meaning. Here is an example:

// test.c

#include <stdio.h>

typedef struct _t {
int a;
int b;
char *c;
} _t;

int main (int argc, char *argv[]){

_t t, *pt;
pt = &t;

t.a = 10;
t.b = 20;
t.c = "Hello!!\n";

printf ("a = %d\n", t.a);
printf ("b = %d\n", t.b);
printf ("c = %s\n", t.c);

printf ("a = %d\n", pt->a);
printf ("b = %d\n", pt->b);
printf ("c = %s\n", pt->c);

// printf ("c = %d\n", pt.a); // ERROR!

printf ("c = %d\n", &pt->a); //to get the pointer to a (it will
// complain because %d expects
//an int while &pt->a is an int *)

return 0;

}


I suggest you to read this reference:

"The C Programming Language" B.W.Kernighan & D.M.Ritchie

On chapter 6 you can find all you need.
 
N

Nick Keighley

the subject was:
"what is the type for this call?"
If i have a :
typedef struct str32{
uint32_t word1;
uint32_t word2;

} word_array;

word_array *my_array;

what would be the data type of this:
myarray->word1

there are no calls in your code so it is meaningless
to ask "what is the type for this call". And if you were
talking about a call I'd expect it to be
"what is the type *of* this call".
 
J

James Kuyper

Neo said:
> typedef struct str32{
> uint32_t word1;
> uint32_t word2;
> } word_array;
>
> word_array *my_array;

Oh my bad, so my c has gotten very rusty. Ok now if I do
my_array.word1 do I get a pointer to word1?

No. You defined my_array as a pointer; the '.' notation is not allowed
on a pointer. If you want a pointer to word1, the correct notation is
&my_array->word1.
 
N

Neo

Neo said:
Oh my bad, so my c has gotten very rusty. Ok now if I do
my_array.word1 do I get a pointer to word1?

being my_array a pointer to a structure this syntax, to me, doesn't have
any meaning. Here is an example:

// test.c

#include <stdio.h>

typedef struct _t {
int a;
int b;
char *c;

} _t;

int main (int argc, char *argv[]){

_t t, *pt;
pt = &t;

t.a = 10;
t.b = 20;
t.c = "Hello!!\n";

printf ("a = %d\n", t.a);
printf ("b = %d\n", t.b);
printf ("c = %s\n", t.c);

printf ("a = %d\n", pt->a);
printf ("b = %d\n", pt->b);
printf ("c = %s\n", pt->c);

// printf ("c = %d\n", pt.a); // ERROR!

printf ("c = %d\n", &pt->a); //to get the pointer to a (it will
// complain because %d expects
//an int while &pt->a is an int *)

return 0;

}

I suggest you to read this reference:

"The C Programming Language" B.W.Kernighan & D.M.Ritchie

On chapter 6 you can find all you need.

I know this pointer and address mechanism but got confused when I
moved from a defines type declaration of a register to a structure
type definition where all the registers form offsets. This made my
read and write functions written for the earlier case unusable as they
reqd a uint32_t * as an argument.
for ex:
#define uart_status ((volatile unsigned int *)(UART0_BASE +
0x0))

changed to -

typedef volatile struct uart_reg_struct
{
uint32_t uart_status;
uint32_t uart_in_en;
---
---
} uart_reg_array;
uart_reg_array *uart_reg = (uart_reg_array *)0x10001000;
read_reg(uart_status);//was working earlier but now
read_reg(uart_reg->uart_status); // became a problem

Anyway, I got the idea and thanks for your feedback.
 
N

Neo

uart_reg_array *uart_reg = (uart_reg_array *)0x10001000;
read_reg(uart_status);//was working earlier but now
read_reg(uart_reg->uart_status); // became a problem

Anyway, I got the idea and thanks for your feedback.

Is there a cleaner way to deal with this struct as I have to take care
of peripheral regs (embedded world!)
The write function which required a pointer to the registers(volatile
too) becomes unwieldy with all this arrows and ampersands so I am
thinking if I should revert back to the old defines declaration.
 
K

Keith Thompson

Neo said:
If i have a :
typedef struct str32{
uint32_t word1;
uint32_t word2;
} word_array;

word_array *my_array;

Your naming is misleading. You use the names "struct str32" and
"word_array" for the same type -- and there's not an array in sight.
And your variable "my_array" is a pointer, not an array. I suspect
that's part of your problem; it's harder to think about things if you
haven't named them clearly.

Let's try changing the names for greater clarity. I personally prefer
not to use typedefs for structures, but I'll use one here. And since
we have a typedef, the struct tag (you used "str32") isn't necessary.
(It would be in some cases, but we'll ignore that.)

typedef struct {
uint32_t word1;
uint32_t word2;
} word_pair;

word_pair *ptr;

This declares a structure type named "word_pair" containing two
uint32_t members. We've also defined the variable "ptr" as a pointer
to word_pair object (but we haven't given it a value).

(Strictly speaking, the struct type is anonymous, and "word_pair" is
just an alias for it, but it's simpler to say that "word_pair" is the
name of the type.)

The "." operator takes a struct and a member name, and yields the
value of that member of the struct.

The "->" operator takes a pointer-to-struct and a member name, and
yields the value of that member of the struct that the pointer points
to; "p->m" is an abbreviation of "(*p).m".
what would be the data type of this:
myarray->word1

In our revised naming scheme, that would be "ptr->word1". It's of
type uint32_t.

Breaking it down, ptr is a pointer to a word_pair; presumably we've
allocated a word_pair structure somewhere and set "ptr" to point to
it.

ptr->word1 means (*ptr).word1
ptr is a pointer to a word_pair object.
*ptr is the word_pair object that it points to.
(*ptr) is the same thing.
(*ptr).word1 is the word1 member of that word_pair object. It's not
the member's address, it's the member itself.
How come it is a uint32_t type and is giving the value of word1? isn't
it still a pointer which is not dereferenced yet?

Nope. The -> operator gives you the member itself, not a pointer to
it. Whatever is on the left hand side of the -> must be a pointer to
struct, and is dereferenced. Whatever is on the right hand side must
be a member name. The result is the value of the member.

(You can also put it on the left hand side of an assignment:
ptr->word1 = 42;
In this case, we don't look at the previous value of the member, we
just assign a new value to it. It's just like an ordinary variable
name, except that a little more work is done to determine what object
it refers to.)
I was thinking I should have to do *(my_array->word1) to get to
uint32_t type, what goes?

Nope. If you want a pointer to the word1 member, you can write
&ptr->word1
The operator precedence is such that this means
&(ptr->word1)
But in this case, you want the value of word1, so ptr->word1 does the
trick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top