I would like to "link" to a structure or member of a structure in Doxygen while displaying the text struct.member. My source code is in C.
For example, let's say I have the myStruct type/structure in C:
typedef struct
{
int member1;
int member2;
} myStruct;
And I would like to link/redirect within my Doxygen comments to documentation on myStruct while showing the text "myStruct.member1"
Example Doxygen Comments for a function:
You will receive the error code MEMBER_1_NOT_VALID if myStruct.member1 is larger than 5.
Where clicking on "myStruct.member1" redirects me to the documentation for myStruct.
I know that if I just have myStruct I could say "\ref myStruct", but doing "\ref myStruct.member1" does not work. Does anyone know how to make the documentation references work?
Any help is appreciated! Thank you.
I think the problem is that you defined the type and the structure together. Doxygen's parser seems to have problems with the mixed declaration of a struct and a typedef. Try to define the structure and the type definition seperately:
struct myStruct_s
{
int member1;
int member2;
};
typedef struct myStruct_s myStruct;
The you can reference the struct members using the tag name of the struct similar to as you already tried:
/**
* ...
* You will receive the error code MEMBER_1_NOT_VALID if \ref myStruct_s.member1
* is larger than 5.
* ...
*/
Related
I have built a struct in two ways, see below (Fig. A & Fig. B). In my .c file I access the struct like so (Fig. C).
Can someone please explain why Figure A makes a compiler error when accessed by Fig. C. Also, why Figure B doesn't cause a compiler error when accessed using Fig. C? Fig.
I can appreciate the syntax, if the struct is being used inside itself, the name needs to be in two places, top and bottom of struct.
Is it related to a 'forward reference' of sorts for the compiler? A good explanation would be appreciated.
//Fig. A
typedef struct
{
uint32_t* block_address;
struct mem_table_entry_t* next_entry_ptr;
}mem_table_entry_t;
typedef struct
{
mem_table_entry_t two_kib[8];
}mem_table_t;
and
//Fig. B
typedef struct mem_table_entry_t
{
uint32_t* block_address;
struct mem_table_entry_t* next_entry_ptr;
}mem_table_entry_t;
typedef struct
{
mem_table_entry_t two_kib[8];
}mem_table_t;
...
//Fig. C
memory_table.two_kib[block].next_entry_ptr = &memory_table.two_kib[block+1];
In snippet A, there is no struct mem_table_entry_t defined [yet] in the struct tag namespace. So you cannot refer to it as in struct mem_table_entry_t* next_entry_ptr;.
Your snippet B is correct.
Note also that the typedef namespace is distinct from the struct tag namespace. This means the the following are not compatible:
mem_table_entry_t two_kib1[8];
struct mem_table_entry_t two_kib2[8];
We all know how to declare a structure in C:
struct Label1{ /* variables */ } Label2; // As I learned
But I want to know why this code works without declaring 'struct name':
typedef struct name s_name;
Or is in fact, does typing the code
struct name;
mean that I declared 'struct name' as a void structure or something like this?
Example of code:
typedef struct Data Data;
struct Data{ /*variables*/ };
If in the first line struct Data is declared as a void one, then in the second it's like I'm redeclaring it with members.
What is the explanation for this point?
Something like:
struct MyStruct;
Is called a forward reference. It creates an incomplete type and tells the compiler there will be a type of that name (and it's a struct - it works likewise for unions), and the details "follow later". Of such a type you cannot define variables, until you complete the type.
typedef struct MyStruct MyType;
Will just define the type name to be that struct. This is still an incomplete type.
However, you can take a pointer to an incomplete type:
MyType *my_t_pointer;
struct MyStruct *my_s_pointer;
This is useful for a struct to have pointers to objects of the same type when you provide the full declaration, "completing" the type:
struct MyStruct {
struct MyStruct *next;
};
Actually this is the only way to create nodes for lists, trees, and all other recursive data-structures. This is a major part of C programs (sometimes hidden).
Also, this mechanism is used to hide implementation details. Functions in the header need only know the struct exists to take/pass pointers to it. The use of these functions need not to know the details of the struct (but this way it cannot allocate it, so the module has to cover all aspects which need to know details on the struct). The full declaration is only inside the implementation file of the module.
These pointers are called "opaque" as one cannot "look through", i.e. access the fields of the struct as they are simply not known to it.
my_module.h:
struct MyStruct;
extern void my_init(struct MyStruct *obj);
my_module.c:
struct MyStruct {
int f1;
...
};
my_init(struct MyStruct *obj)
{
...
}
The typedef declares s_name as an alias for struct name so that you can declare variables, e.g.:
s_name *sptr;
The line
struct name;
declares that there is a struct type called name without defining its content. This is usually done in order to be able to declare variables as pointers to the struct type. You cannot declare variables of the actual struct type until it has been defined.
As usual, Wikipedia's article on structs is less than clear. It gives the syntax for structs as this:
[typedef] struct [struct_name]
{
type attribute;
type attribute2;
/* ... */
[struct struct_name *struct_instance;]
} [struct_name_t] [struct_instance];
What would the typedef keyword do here?
What does the [struct_name] mean? (Is it the name you're giving to the new struct data type?)
What does the [struct_name_t] mean?
what does the [struct_instance] mean? (Is it creating a single instance of the struct?)
I presume [struct struct_name *struct_instance;] creates a pointer in the struct which would point to a second instance of the struct). Correct?
I would greatly appreciate an example: Say I have three files: main.c, sub.c and sub.h. I want to declare an instance of a struct in sub.h, and instantiate and use it it in sub.c. Say I want a Song type struct, with members char name[20] and char artist[10], and say I want to make an instance, mySong, {"Me singing", "Me"}, how would this look in sub.c and sub.h?
Thanks
•What would the typedef keyword do here?
It would allow you to create a typedef of your structre, just like any other type. This allow you to not have to type struct xxx struct_name everytime. You don't need this, hence the []
•What does the [struct_name] mean? (Is it the name you're giving to the new struct data type?)
Yes, if you chose too. You can also make a nameless struct so you don't need to give it a name.
•What does the [struct_name_t] mean?
That's the typedef'd name, if you chose to typedef the struct
•what does the [struct_instance] mean? (Is it creating a single instance of the struct?)
Yes, it's for creating one or more instance(s) of the sturct
•I presume [struct struct_name *struct_instance;] creates a pointer in the struct which would point to a second instance of the struct). Correct?
Right, this would be usefull for a "next" type pointer in a linked list.
struct example:
typedef struct foo{
int count;
struct foo *next;
} foo_t myfoo;
is an example of that filled in; this allows you to declare a new struct via:
foo_t new_foo_struct;
because of the typedef and typedef'd name. If you omit those like this:
struct foo{
int count;
struct foo *next;
} myfoo;
Now you'd have to use the struct key word for every instance, such as:
struct foo new_foo_struct;
to break it up over more than 1 file:
/*sub.h*/
typedef struct{
char name[20];
char artist[10];
}song;
Then in the source:
/*sub.c*/
#include "sub.h"
/*this needs to go into a function or something...*/
song mysong;
strcpy(mysong.name, "Mesinging");
strcpy(mysong.artist, "Me");
That article is just wrongly mixing different concepts, rectified this now. A struct is declared through
struct tagname {
... fields ...
};
that's just it, only that the tagname part is optional in some contexts.
In addition you may
declare an alias for the struct type through typedef
or a variable of the struct type
"in one go", but I don't think that it is good style and should be separated.
sub.h
------
typedef struct{
char name[20];
char artist[10];
}song;
sub.c
----
song mysong={"Me Singing","Me"};
typedef struct struct_name
{
char name[20];
char artist[10];
}struct_name_t structInstance;
typedef - this means that you are creating a new type (struct_name_t)
So, in C code you can create an instance like this:
struct_name_t myVariable;
or you can explicitly write:
struct struct_name myVariable;
The structInstance at the end means that you want to create an instance of your struct at the same moment you defined it (and the name of that variable is structInstance). It's not something you will use all the time, but it is useful in some situations.
If you want to create an instance of your struct and assign/initialize members at the creation time, you can do it like this:
struct_name_t myVariable = { "Foo", "bar" };
The 'name' member will contain "Foo" and the artist member will contain "bar".
Note:
If you write this:
struct_name_t myVariable = { 0 };
That will fill your entire struct with zeroes!
I am doing feature enhancement on a piece of code, and here is what i saw in existing code. If there is a enum or struct declared, later there is always a typedef:
enum _Mode {
MODE1 = 0,
MODE2,
MODE3
};
typedef enum _Mode Mode;
Similary for structure:
struct _Slot {
void * mem1;
int mem2;
};
typedef struct _Slot Slot;
Can't the structures be directly declared as in enum? Why there is a typedef for something as minor as underscore? Is this a coding convention?
Kindly give good answers, because i need to add some code, and if this is a rule, i need to follow it.
Please help.
P.S: As an additional info, the source code is written in C, and Linux is the platform.
In C, to declare a varaible with a struct type you would have to use the following:
struct _Slot a;
The typedef allows you to make this look somewhat neater by essentially creating an alias. And allowing variable declaration like so:
Slot a;
In C there are separate "namespaces" for struct and typedef. Thus, without a typedef you would have to access Slot as struct _Slot, which is more typing. Compare:
struct Slot { ... };
struct Slot s;
struct Slot create_s() { ... }
void use_s(struct Slot s) { ... }
vs
typedef struct _Slot { ... } Slot;
Slot s;
Slot create_s() { ... }
void use_s(Slot s) { ... }
Also see http://en.wikipedia.org/wiki/Struct_(C_programming_language)#typedef for details, like possible namespace clash.
If the following is a structure:
struct _Slot {
void * mem1;
int mem2;
};
you need the following to declare a variable:
struct _Slot s;
Notice the extra struct before _Slot. It seems more natural to declare a variable like Slot s, isn't it?
If you want to get rid of extra struct, you need a typedef:
typedef struct _Slot Slot;
Slot s;
It's sort of code obfuscation technique which only make sense in small amount of cases.
People say it's more natural to not write "struct" and other subjective things.
But objectively, one at least a) can't forward declare such typedeffed struct, b) have to jump through one hoop when using ctags.
I have a struct with a callback function, the callback function needs a pointer to the structure in order to do its operation. How do I properly define these elements such that is will compile without warnings?
typedef struct {
// some fields required for processing...
int (*doAction)(struct pr_PendingResponseItem *pr);
} pr_PendingResponseItem;
If I remove the "struct" attribute on the pr parameter, I get an error. If I leave it in, I get a warning:
"its scope is only this definition or declaration, which is probably not what you want"
It all works, but I would like to know the proper way to define such a structure.
Also related, is defining a self referential structure:
typedef struct LinkedItem_ {
LinkedItem_ * prev;
LinkedItem_ * next;
void * data;
} LinkedItem;
(I think this is correct, but additional thoughts are welcome if it is related to the question.)
Your function pointer references a struct pr_PendingResponseItem, but you haven't declared a struct pr_PendingResponseItem. You just have an unnamed structure typedef'ed to the name pr_PendingResponseItem (and that name isn't established yet).
Give the struct a name:
struct pr_PendingResponseItem {
// some fields required for processing...
int (*doAction)(struct pr_PendingResponseItem *pr);
} ;
typedef struct pr_PendingResponseItem pr_PendingResponseItem;
There are two ways to do it — for both your example structures. They are essentially isomorphic.
Use a structure tag, as already shown in various other answers.
typedef struct pr_PendingResponseItem
{
// some fields required for processing...
int (*doAction)(struct pr_PendingResponseItem *pr);
} pr_PendingResponseItem;
typedef struct LinkedItem
{
struct LinkedItem *prev;
struct LinkedItem *next;
void * data;
} LinkedItem;
Use typedef to give a name to an incomplete structure type and use the typedef in the structure definition.
typedef struct pr_PendingResponseItem pr_PendingResponseItem;
struct pr_PendingResponseItem
{
// some fields required for processing...
int (*doAction)(pr_PendingResponseItem *pr);
};
typedef struct LinkedItem LinkedItem;
struct LinkedItem
{
LinkedItem *prev;
LinkedItem *next;
void * data;
};
Note that the structure tags are in a different namespace from the typedef names, so there is no need to use different names for the typedef and structure tag. Also note that in C++ the typedef would be unnecessary.
something like this
typedef struct _pr_PendingResponseItem_ {
// some fields required for processing...
int (*doAction)(struct _pr_PendingResponseItem_ *pr);
} pr_PendingResponseItem;
should fix it.
(Tested & works)
Adding to the answer by nos above.
The key insight here is that when dealing with a declaration like "typedef struct name1 {} name2;", you are actually declaring two types i.e. "struct name1 {};" and then "typedef struct name1 name2;", where "struct name1" is a type and you have to use the syntax "struct name1" to refer to it, and "name2" is a type, and you refer to it as "name2". You are allowed to leave "name1" out, in which case you just define the second type and the first one remains a anonymous struct.
Now, in the first case, if you want to refer to the type "struct pr_PendingResponseItem", you need to declare that type, instead of the anonymous struct you have declared. So, change your struct declaration to "struct pr_PendingResponseItem".
In the second case, you are trying to refer to a struct type as a forward reference (i.e. referring to it before its definition is complete), which is allowed, but to refer to a struct type, the required syntax is "struct name". So you need to replace forward references to "LinkedItem_" in your definition with "struct LinkedItem_".