I would like to document a struct as a member of a struct, in a style, that there will be clickable link to structure precalculated same as on calibrator_calibration_t and after click it will show me all members of precalculated.
Generated HTML:
I've tried many different approaches but none of them worked as I needed. Any tip?
/**
* #struct filter_t
* #brief Filter structure
*/
typedef struct
{
calibrator_calibration_t calibration; ///< Copied calibration
blackbox_weight_id_e weight_id;
struct
{
float slope;
float above_mixed;
float under_mixed;
float above_male;
float under_male;
float above_female;
float under_female;
uint32_t stable_counter_minimum;
} precalculated; ///< Precalculated values (for faster calculation) based on settings
} filter_t;
If you want the type of structure member precalculated to be documented with a name and a link to separate documentation of that type, then you must give that type a name or tag. You have not done that. C does not allow you to name it (via typedef) when its definition is inside a struct definition, however, and it is poor style to tag it in that context.
If you can get over your apparent aversion to structure tags and are also unconcerned with the stylistic problems involved, then I anticipate that adding a tag would induce Doxygen to do what you want:
typedef struct
{
calibrator_calibration_t calibration; ///< Copied calibration
blackbox_weight_id_e weight_id;
struct precalc // Note the structure tag here
{
float slope;
float above_mixed;
float under_mixed;
float above_male;
float under_male;
float above_female;
float under_female;
uint32_t stable_counter_minimum;
} precalculated; ///< Precalculated values (for faster calculation) based on settings
} filter_t;
But if you are going to tag the structure type then it would be better form to move it out of the host structure definition, and if you're going to do that, then it appears that your standard convention would be to name it instead of tagging it:
typedef struct {
float slope;
float above_mixed;
float under_mixed;
float above_male;
float under_male;
float above_female;
float under_female;
uint32_t stable_counter_minimum;
} precalculated_t;
typedef struct
{
calibrator_calibration_t calibration; ///< Copied calibration
blackbox_weight_id_e weight_id;
precalculated_t precalculated; ///< Precalculated values (for faster calculation) based on settings
} filter_t;
Related
I just started with C and I am reading head first C. According to that book's I defined a union and try to declare variables in it. But it doesn't give the expected output.Here is the code
#include <stdio.h>
typedef union{
short count;
float weight;
float volume;
} quantity;
int main()
{
quantity q;
q.count = 4;
q.weight = 1.7;
q.volume = 3.7;
printf("count = %i\tweight = %.2f\tvolume = %2.f\t", q.count, q.weight, q.volume);
}
Here is the output
count = -13107 weight = 3.70 volume = 3.70
Why am I getting a negative number for count and same floating-point for weight and volume?
A union allows to store different data types in the same memory location. You can define a union with many members, but only one member can contain a value at any given time. That is why only the last element you initialized is printed correctly. What you might be looking for is a struct.
typedef struct {
short count;
float weight;
float volume;
} quantity;
You must have missed the section in your text book that said that all members of a union share the exact same memory, and that the value of all member will be the value of the memory bit pattern used in the last assignment to a member.
Since you set the volume member last, then all member will have the same in-memory bit pattern as the float value 3.7.
And integers and floating point values have different bit patterns in memory, so the value for count will seem almost random or garbage.
If you want three distinct and separate members you need a structure and not a union.
A union has shared memory for each of its members, so it can only store one of them at a time. If you write to one member and read another one, you'll get something else out.
If you want to be able to hold all of these values at once, you want a struct.
typedef struct {
short count;
float weight;
float volume;
} quantity;
A union is a special data type available in C that allows to store different data types in the same memory location. You can define a union with many members, but only one member can contain a value at any given time.
so if you want to store value in all three variables then you should use struct.
typedef struct {
short count;
float weight;
float volume;
}
What is the proper way to passing struct into function?
Both solutions works fine, but is there any significant difference?
struct sensor
{
int32_t temperature;
}BME280;
int32_t read_temperature(struct sensor *BME)
{
}
vs
typedef struct sensor
{
int32_t temperature;
}BME2801;
int32_t read_temperature(BME2801 *BME)
{
}
int main(void)
{
BME2801 BME280;
}
In the first example, you are defining a structure of type struct sensor, and declaring a global variable called BME280 of the same type. Your read_temperature function is taking a pointer to a struct sensor. Your variable BME280 is not being used for anything.
In the second example, you are defining a structure of type struct sensor, and using typedef to create a new type name (BME2801), which will allow you to type BME2801 instead of struct sensor in your code. In your main function you are declaring a BME2801 (aka struct sensor) type variable with the name BME280. Your read_temperature function works the same, just as before.
These are two different examples and definitely not equivalent.
Your use of pointers to pass your structure by reference is good. Typically you want to pass all structures using pointers, especially if it is particularly big struct. Just cut out BME280 from your first example and you're golden.
Now comes the question of whether to use typedef to create a new type name to refer to a struct sensor. If it improves legibility and clarity, by all means do it. Assuming you want to refer to each struct sensor as BME2801, your second example does it correctly. I would argue that struct sensor is significantly clearer than BME2801 though. Usually you would define your structure in one of two ways and use it thusly:
struct sensor
{
int32_t temperature;
};
int32_t read_temperature (struct sensor *BME)
{
}
int main (void)
{
struct sensor BME280;
/* Initialize your struct with appropriate values here */
read_temperature (&BME280);
}
Or you can use typedef. This is typically done with structures to remove the requirement to use the keyword struct. C++ does this automatically without the explicit typedef.
typedef struct sensor
{
int32_t temperature;
}sensor;
/* 'sensor' now refers to the type 'struct sensor' */
int32_t read_temperature (sensor *BME)
{
}
int main (void)
{
sensor BME280;
/* Initialize your struct with appropriate values here */
read_temperature (&BME280);
}
Whether to typedef a struct to simply omit the struct keyword is a matter of style. The Linux kernel coding style suggests almost never using a typedef for structures unless you actively hiding its contents and encourage developers using your struct to use special accessor functions you provided. I follow this advice in my own code, but there are other opinions out there.
I've written a small matrix library as part of a larger project I am working on. It was important to have zero-cost transpositions, so I used/abused unions. The code itself works fine (provided below), but when it came to document with Doxygen, it combines all of the documentation for both struct matrix_r and union matrix_r into a single item. That is, there are only generated pages for struct matrix_r and struct matrix_c, but those two pages describe matrix_r and matrix_c as unions, with concatenated #brief text and concatenated attributes (from both the struct and union declarations).
I am very, very new to Doxygen, but I have been unable so far to figure out how to get it to treat these as separate documentation items. Any ideas?
#include <stddef.h>
/// #brief internal stuct for row-major matrices
struct matrix_r {
int *data; ///< raw pointer backing matrix
size_t m; ///< the number of rows
size_t n; ///< the number of cols
};
/// #brief internal struct for col-major matrices
struct matrix_c {
int *data; ///< raw pointer backing matrix
size_t n; ///< the number of cols
size_t m; ///< the number of rows
};
/// #brief user-facing typedef for row-major matrices
typedef union {
struct matrix_r id; ///< identity view of matrix
struct matrix_c tr; ///< transposed view of matrix
int* flat; ///< flattened view of matrix
} matrix_r;
/// #brief user-facing typedef for row-major matrices
typedef union {
struct matrix_c id; ///< identity view of matrix
struct matrix_r tr; ///< transposed view of matrix
int* flat; ///< flattened view of matrix
} matrix_c;
Structural commands start with a backslash (\), or (#) followed by a command name and one or more parameters. For instance, if you want to document the class Test , you could have put the following documentation block somewhere in the input that is read by doxygen:
/*! \class Test
\brief A test class.
A more detailed class description.
*/
Straight from the manual, here are some other commands:
Here the special command \class is used to indicate that the comment
block contains documentation for the class Test. Other structural
commands are:
\struct to document a C-struct.
\union to document a union.
\enum to document an enumeration type.
\fn to document a function.
\var to document a variable or typedef or enum value.
\def to document a #define.
\typedef to document a type definition.
\file to document a file.
\namespace to document a namespace.
\package to document a Java package.
\interface to document an IDL interface.
Edit:
I believe this is the way Doxygen is designed to work. See the
documentation here:
http://www.doxygen.nl/autolink.html
in the section "typedefs". It says:
Typedefs that involve classes, structs and unions, like
typedef struct StructName TypeName
create an alias for StructName, so links will be generated to
StructName, when either StructName itself or TypeName is encountered.
Doxygen considers the union tag name to be "the real thing",
not the typedef (which is considered like an alias of "the real
thing"). I'd recommend this:
/*!#brief The documentation of the union Name*/
typedef union Name
{
//.....
}Name;
Xcode automatically generates code for submitting OpenCL kernels to dispatch queues but it seems that it generates invalid code which can't be compiled for one of my kernels. The problem is with a struct definition:
typedef struct {
float4 position; ///< The point position.
float4 velocity; ///< The point velocity.
float intensity; ///< The point intensity.
int links[6]; ///< The point links specified as indexes for other points in the array.
float align; ///< Dummy for alignment.
} PointElement;
This code is generated by Xcode:
typedef struct {
cl_float4 position;
cl_float4 velocity;
cl_float intensity;
int [6] links;
cl_float align;
} _PointElement_unalign;
I'm not expert at obscure C syntax variants but it surely int [6] links; is not valid C and therefore does not compile.
Why does Xcode do this? Have I done something wrong myself or is this a bug?
C11 adds, among other things, 'Anonymous Structs and Unions'.
I poked around but could not find a clear explanation of when anonymous structs and unions would be useful. I ask because I don't completely understand what they are. I get that they are structs or unions without the name afterwards, but I have always (had to?) treat that as an error so I can only conceive a use for named structs.
Anonymous union inside structures are very useful in practice. Consider that you want to implement a discriminated sum type (or tagged union), an aggregate with a boolean and either a float or a char* (i.e. a string), depending upon the boolean flag. With C11 you should be able to code
typedef struct {
bool is_float;
union {
float f;
char* s;
};
} mychoice_t;
double as_float(mychoice_t* ch)
{
if (ch->is_float) return ch->f;
else return atof(ch->s);
}
With C99, you'll have to name the union, and code ch->u.f and ch->u.s which is less readable and more verbose.
Another way to implement some tagged union type is to use casts. The Ocaml runtime gives a lot of examples.
The SBCL implementation of Common Lisp does use some union to implement tagged union types. And GNU make also uses them.
A typical and real world use of anonymous structs and unions are to provide an alternative view to data. For example when implementing a 3D point type:
typedef struct {
union{
struct{
double x;
double y;
double z;
};
double raw[3];
};
}vec3d_t;
vec3d_t v;
v.x = 4.0;
v.raw[1] = 3.0; // Equivalent to v.y = 3.0
v.z = 2.0;
This is useful if you interface to code that expects a 3D vector as a pointer to three doubles. Instead of doing f(&v.x) which is ugly, you can do f(v.raw) which makes your intent clear.
struct bla {
struct { int a; int b; };
int c;
};
the type struct bla has a member of a C11 anonymous structure type.
struct { int a; int b; } has no tag and the object has no name: it is an anonymous structure type.
You can access the members of the anonymous structure this way:
struct bla myobject;
myobject.a = 1; // a is a member of the anonymous structure inside struct bla
myobject.b = 2; // same for b
myobject.c = 3; // c is a member of the structure struct bla
Another useful implementation is when you are dealing with rgba colors, since you might want access each color on its own or as a single int.
typedef struct {
union{
struct {uint8_t a, b, g, r;};
uint32_t val;
};
}Color;
Now you can access the individual rgba values or the entire value, with its highest byte being r. i.e:
int main(void)
{
Color x;
x.r = 0x11;
x.g = 0xAA;
x.b = 0xCC;
x.a = 0xFF;
printf("%X\n", x.val);
return 0;
}
Prints 11AACCFF
I'm not sure why C11 allows anonymous structures inside structures. But Linux uses it with a certain language extension:
/**
* struct blk_mq_ctx - State for a software queue facing the submitting CPUs
*/
struct blk_mq_ctx {
struct {
spinlock_t lock;
struct list_head rq_lists[HCTX_MAX_TYPES];
} ____cacheline_aligned_in_smp;
/* ... other fields without explicit alignment annotations ... */
} ____cacheline_aligned_in_smp;
I'm not sure if that example strictly necessary, except to make the intent clear.
EDIT: I found another similar pattern which is more clear-cut. The anonymous struct feature is used with this attribute:
#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
#define __randomize_layout __attribute__((randomize_layout))
#define __no_randomize_layout __attribute__((no_randomize_layout))
/* This anon struct can add padding, so only enable it under randstruct. */
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end } __randomize_layout;
#endif
I.e. a language extension / compiler plugin to randomize field order (ASLR-style exploit "hardening"):
struct kiocb {
struct file *ki_filp;
/* The 'ki_filp' pointer is shared in a union for aio */
randomized_struct_fields_start
loff_t ki_pos;
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
void *private;
int ki_flags;
u16 ki_hint;
u16 ki_ioprio; /* See linux/ioprio.h */
unsigned int ki_cookie; /* for ->iopoll */
randomized_struct_fields_end
};
Well, if you declare variables from that struct only once in your code, why does it need a name?
struct {
int a;
struct {
int b;
int c;
} d;
} e,f;
And you can now write things like e.a,f.d.b,etc.
(I added the inner struct, because I think that this is one of the most usages of anonymous structs)