System Verilog Associative Array - associative-array

Is it possible to define a associated array of different element types - something like below ?
typedef enum {M1, M2} mod_t;
typedef struct {...} m1_reg_t;
typedef struct {...} m2_reg_t;
array[mod_t] = {
M1: { string name;
m1_reg_t cfg
}
M2: { string name;
m2_reg_t cfg;
int m2_indx;
}
}

No, all arrays must have the same element type.
If you really want an array with just two elements of a different type, use another struct instead of an array.
typedef struct {
string name;
m1_reg_t cfg;
} M1_t;
typedef struct {
string name;
m2_reg_t cfg;
int m2_indx;
} M2_t;
struct { M1_t M1;
M2_t M2;
} opcodes;
But if you are looking for an array of many elements where each element might hold a different opcode, consider a dynamic array of tagged unions.
typedef union tagged {
struct {
string name;
m1_reg_t cfg;
} M1;
struct {
string name;
m2_reg_t cfg;
int m2_indx;
} M2;
} opcode_t;
opcode_t opcodes[];
Accessing tagged unions requires pattern matching statements. See section 12.6 in the 1800-2017 LRM.

Related

Double LinkList in data structure

When I create a double Linklist By using C(C99), if I add the code: struct DNonde***first**=NULL; on the main function when running Display function the parameter first = NULL. If I remove the additional code: struct DNonde *first = NULL; then structure point: first will normally running as the linklist's first node's address and the Display funtion will also normally running.
However the question is I am using the Create function to create double Linklist after the code:struct DNonde*first=NULL;thus, it will not influence the latter codes, and when I debug the codes it shows me that the double Linklist is created successfully but when in Display function the first = NULL. And why it cause that?
Below is the source code
#include "stdio.h"
#include "stdlib.h"
struct DNonde
{
struct DNonde *preview;
int data;
struct DNonde *next;
}*first=NULL;
void Create(int a[],int length)
{
struct DNonde*tem = NULL;
first =(struct DNonde*)malloc(sizeof(struct DNonde));
first->preview=NULL; first->data=a[0]; first->next=NULL;
struct DNonde *control = first;
for(int i=1;i<length;i++)
{
tem =(struct DNonde*)malloc(sizeof(struct DNonde));
control->next = tem;
tem->preview = control; tem->data = a[i]; tem->next=NULL;
control = tem;
}
}
void Display(struct DNonde*first)
{
do
{
printf("%d ",first->data);
first=first->next;
}while(first != NULL);
}
int main()
{
int a[]={1,3,4,5};
struct DNonde*first=NULL;
Create(a, 4);
Display(first);
}

Structure pointer dereference

I am trying to pass a structure of point array as shown, how can I correctly dereference the address to change the value the address points to.
// header file "header.h"
typedef struct {
double x;
double y;
} Pointbase;
typedef Pointbase *XYpt;
typedef struct {
XYpt xy[1];
} ChartPointsbase;
typedef ChartPointsbase **PointArray;
#include "header.h"
...
void npCluster(double drop, XYpt *newpt, PointArray outpts)
{
double xx[2]={-15, 100};
int i;
outpts = (PointArray)malloc(sizeof(PointArray) * 2);
for (i=0;i<2; i++)
{
(*(*outpts)->xy[i])->x=xx[i];
(*(*outpts)->xy[i])->y=drop;
}
}
The complier likes the following line but does not compute
(*outpts)->xy[i]->y=drop;
Any suggestions will be most appreciated.
I figured it out for "c" compiler as follows:
Define struct with two 1D arrays each of size dimsize, allocate memory to handles, set the size =k, and dereference as follows:
for (i=0; i<k; i=i++)
{
(*(outpts->xx))->dat[i]=135*i+j;
(*(outpts->yy))->dat[i]=drop;
}
For further nesting, say struct array of the above with two unequal point arrays, where cht is an array of PointArray
typedef struct {
int32 dimSize;
C1Hdl cht[1];
} XYchartCluster;
// initialize 1st array
for (i=0; i<k; i=i++)
{
(*(*(xycht)->cht[0])->xx)->dat[i]=135*i+j;
(*(*(xycht)->cht[0])->yy)->dat[i]=drop;
}
// initialize 2nd array with values from point npt
for (i=0; i<sz; i=i++)
{
(*(*(xycht)->cht[1])->xx)->dat[i]=npt->x;
(*(*(xycht)->cht[1])->yy)->dat[i]=npt->y;
}
/*
Note: size of each array in chart should be initialized and
memory assigned (dynamically changing size)
*/

How use pointer to access variables of public struct

I have a pointer to a class and I'm trying to use it to access the class' public struct. I've looked at access member var using ptr, as well as access memb struct from ptr class, but when you look at the links, it's not what I'm trying to do.
I'm having trouble doing something that will build. The examples in the code are without pointers, but I have a pointer to IFM to work with. Does anyone know how to use the pointer (to IFM) to access the public struct (in IFM)?
//snippet of code that is trying to access struct in IFM:
const IFM *pJunk = rData1.getM(); //this is fine
pJunk->JunkStruct::Junk.xs; //this doesn't work
The struct in IFM.h:
class IFM final : public IFO
{
public:
typedef struct JunkStruct
{
JunkStruct() = default;
~JunkStruct() = default;
JunkStruct(const IFM::JunkStruct&) = default;
JunkStruct(const double& first, const double& second, const double& third, const double& fourth, const double& fifth, const double& sixth) :
xs(first), ysk(second), xsk(third), ys(fourth), x(fifth), y(sixth)
{}
IFM::JunkStruct& operator=(const IFM::JunkStruct&) = default;
// Initialized
double xs = 1.0;
double ys = 0.0;
double xsk = 0.0;
double ysk = 1.0;
double x = 0.0;
double y = 0.0;
} Junk;
...
OPs member is private. It is designed to be hidden. Nothing to see here.
The struct is just a type. If no members in IFM is of type JunkStruct there is no data there to be accessed. To use that inner type you can see this minimal example
struct Outer
{
struct Inner{
int innerMember;
};
};
int main() {
Outer::Inner inner;
inner.innerMember = 4;
std::cout << inner.innerMember << "\n";
Outer outer;
Outer* outerP = &outer;
outer-> No access to innerMember, it does not exist.
}
If on the other hand, the struct would not be a typedef but just a struct, that definition would be akin to:
struct Outer
{
struct Inner{
int innerMember;
};
Inner outerMemberInner; //
};
int main() {
Outer outer;
Outer* outerP = &outer;
outerP->outerMemberInner.innerMember = 4;
// this might be what you are looking for
std::cout << outerP->outerMemberInner.innerMember;
}
With Junk as outerMemberInner.
The type JunkStruct aliased Junk belongs to the type IFM, not to IFM objects or pointer.

How to properly use qRegisterMetaType with multidimensional arrays?

I want to use something like
typedef double Matrix[4][4];
to represent transformations and also pass them around with the QT signal/slot mechanism. But when I use
Q_DECLARE_METATYPE(Matrix)
it throws an error in qmetatype.h at this function
void *qMetaTypeConstructHelper(const T *t)
{
if (!t)
return new T();
return new T(*static_cast<const T*>(t));
}
saying: "error C2075: 'Target of operator new()' : array initialization needs curly braces"
Q_DECLARE_METATYPE(T) requires the type T to be default-constructable, copiable and destructable. Your Matrix type is not copiable, thus you can't use Q_DECLARE_METATYPE on it.
Workaround: use a class.
// copiable, C++98 brace-initializable, etc.
struct Matrix {
double data[4][4];
};
Ideally you should be using eigen3 and its types. Alternatively, wrap your type in a class. Once you do it, you might as well have the class do more than be a mere wrapper. Eventually, you'll see that eigen3 is the only sane way to proceed. Probably when you get to this point:
#include <cstring>
class Matrix {
double m_data[4][4];
public:
typedef double (*Data)[4];
Matrix() {}
Matrix(const Matrix & other) { memcpy(m_data, other.m_data, sizeof m_data); }
Matrix & operator=(const Matrix & other) { memcpy(m_data, other.m_data, sizeof m_data); return *this; }
Matrix & operator=(const Data other) { memcpy(m_data, other, sizeof m_data); return *this; }
operator Data() { return m_data; }
};
int main()
{
double mat1[4][4];
Matrix mat2;
mat2[3][3] = 1;
mat2 = mat1;
return 0;
}

assignment from incompatible pointer type (struct) c

for the struct
typedef struct Recording_Settings recording_settings;
struct Recording_Settings
{
gchar *profile;
gchar *destination;
};
recording_settings rec_settings;
I get a warning when I try to do this
static void profile_combo_change_cb(GtkComboBox *combo, gpointer userdata)
{
GtkTreeIter iter;
GtkTreeModel *model;
/* Grab the encoding profile choosen */
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) {
gchar *media_type;
gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &media_type, -1);
rec_settings.profile = rb_gst_get_encoding_profile(media_type); // Warning: assignment from incompatible pointer type
g_free (media_type);
}
}
Am I misunderstanding or missing something?
Thanks.
The type of rb_gst_get_encoding_profile seems to be
GstEncodingProfile *rb_gst_get_encoding_profile (const char *media_type);
but you assign its return value to a gchar *.
GstEncodingProfile is a struct type, as far as I can determine (typedef struct _GstEncodingProfile GstEncodingProfile;), and gchar is probably a typedef for a character type (most likely typedef char gchar; from glib). So the types would be incompatible.

Resources