C++ object looks like its being used as struct [duplicate] - c++

This question already has answers here:
What is the use of Struct Tag name in C programming?
(3 answers)
What are the advantages of differentiating type/tag names for a typedef in C?
(3 answers)
Does typedef of a structure without tag creates distinct type each time it is used and if not why?
(2 answers)
Closed 6 months ago.
In the following code, I thought saCmdQueue_s is a struct and saCmdQueue_t is an object of type saCmdQueue_s. But then I see the last line looks like they are using saCmdQueue_t to set the type for an object named sa_queue[SA_QSIZE]. Can some help me understand.
typedef struct saCmdQueue_s {
uint8_t *buf;
int len;
} saCmdQueue_t;
#define SA_QSIZE 6 // 1 heartbeat (GetSettings) + 2 commands + 1 slack
static saCmdQueue_t sa_queue[SA_QSIZE];

In C++, when struct is declared, usage is different according to declare type.
If struct is declared as typedef type, you can write other name at the end of struct. Other name is the new name of the type - struct you declared.
Otherwise, if struct is declared as usual type, the result is the following.
struct saCmdQueue_s {
uint8_t* buf;
int len;
} saCmdQueue_t;
#define SA_QSIZE 6 // 1 heartbeat (GetSettings) + 2 commands + 1 slack
saCmdQueue_t sa_queue[SA_QSIZE];
Error: variable "saCmdQueue_t" is not a type name
If you write typedef in front of struct, the struct is declared the type like data type(int, char, string, vector, ...).

Related

What does this nested struct declaration mean? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
#include <bits/stdc++.h>
using namespace std;
struct {
struct {
struct {
char *OwO[12];
}iwi;
}uwu;
}owo;
int main() {
*owo.uwu.iwi.OwO = "What's this?";
printf("%s\n", *owo.uwu.iwi.OwO);
return 0;
}
Hi guys I don't know how this code actually work? Can anyone explain this to me?
Consider for example this declaration
struct {
char *OwO[12];
}iwi;
It at first declares an unnamed structure with one data member that has the type of an array with 12 elements of the type char *. And then it declares an object named iwi of the structure.
So to access the data member OwO of the object iwi you can use the expression
iwi.OwO
that returns lvalue of the array OwO.
If to apply the operator * to the expression then the array OwO is implicitly converted to pointer to its first element and has the type char **. Dereferencing the pointer we get the first element of the array of the type char *.
We can assign the element with a string literal as
*iwi.OwO = "What's this?";
That is the first element of the array that has the type char * now gets the address of the string literal.
Here is a demonstrative program
#include <stdio.h>
struct {
char *OwO[12];
} iwi;
int main(void)
{
*iwi.OwO = "What's this?";
printf( "%s\n", *iwi.OwO );
return 0;
}
Its output is
What's this?
In the original code this unnamed structure is included into two other unnamed structures
struct {
struct {
struct {
char *OwO[12];
}iwi;
}uwu;
}owo;
That is with have object owo of the unnamed outer structure that has data member uwu of the enclosed unnamed data structure that in turn has data member iwi of the most inner unnamed structure.
So to access the data member OwO we have to list all names of object
owo.uwu.iwi.OwO
So we have gotten an access to the most inner data member OwO. And now dereferncing the expression as it was shown in the demonstrative program above we initialize the first element of the array with the string literal "What's this?".
And in the same way we can output it using this full expression
printf("%s\n", *owo.uwu.iwi.OwO);
It's several nested unnamed struct types.
Here is the same thing using named types, and indexing instead of dereferencing.
struct Inner
{
char* OwO[12];
};
struct Middle
{
Inner iwi;
};
struct Outer
{
Middle uwu;
};
Outer owo;
int main() {
owo.uwu.iwi.OwO[0] = "What's this?";
printf("%s\n", owo.uwu.iwi.OwO[0]);
return 0;
}

Function struct points to other function of other struct [duplicate]

This question already has answers here:
struct pointer function points to other function of other struct
(3 answers)
Closed 6 years ago.
I'm trying to point a structure function to another function of another structure,
Plase consider this:
// Main Structure:
typedef struct
{
int GetValA(int a)
{
return a * 2;
}
} x;
typedef struct
{
int(*HGetValA)(int); // Pointer function
} hookx;
// Then
int main()
{
x v1;
hookx* v2;
v2 = (hookx*)&v1; // or 0x0 memory address
// Now declaring pointer function
v2->HGetValA = (int(*)(int))&v1.GetValA; // Pointing to function of the main structure.
}
for me, this looks good, but at compile time gives me the error:
[Warning] converting from 'int (x::)(int)' to 'int ()(int)'
[-Wpmf-conversions]
The pointer points to a member from class/struct does NOT really means to a address, it just points as an offset from this.
So the pointer type out of the class/struct (like in your code, int ()(int)) is different from the inner (like, int (::)(int)).
You have to declare the pointer with a class/struct name that seem to be a scope (and it does).

Colon : used in variable initialization? [duplicate]

This question already has answers here:
What does a colon in a struct declaration mean, such as :1, :7, :16, or :32?
(3 answers)
Closed 7 years ago.
I found this line here:
uint32 bIsHungry : 1;
... and I've never seen this syntax used to initialize a variable.
I'm used to seeing this:
uint32 bIsHungry = 1;
It looks kind of like an initialization list, but for a single field?
What is it, what does it do, why should I care?
That line is a bit field declaration and it declares a data member with an explicit bit-level size
Example from cppreference:
#include <iostream>
struct S {
// three-bit unsigned field,
// allowed values are 0...7
unsigned int b : 3;
};
int main()
{
S s = {7};
++s.b; // unsigned overflow
std::cout << s.b << '\n'; // output: 0
}
Notice that in the example above the unsigned overflow is defined behavior (same doesn't apply if b were declared as a signed type)
The documentation you links also states that
Boolean types can be represented either with the C++ bool keyword or as a bitfield
Regarding why should I care I recommend reading this other question
It is not initialization, it is a fragment of a declaration.
struct {
// ...
uint32 bIsHungry : 1;
// ...
};
declares a bIsHungry as a bitfield member of the struct. It says that bIsHungry is an unsigned int whose length is 1 bit. Its possible values are 0 and 1.
Read more about bitfields: http://en.cppreference.com/w/c/language/bit_field
This is bitfield declaration, Declares a class data member with explicit size, in bits.

C/C++: size of a typedef struct containing an int and enum == sizeof(int)?

I am using gcc version 4.3.3 on my Ubuntu (i686). I have written a stripped down test program to describe my lack of understanding and my problem. The program shall tell me the size of the struct, which I implemented. So I have a typedef struct for a Message and a little main to play around:
#include <stdio.h>
typedef struct {
int size;
enum {token=0x123456};
} Message;
int main(int argc, char * argv[])
{
Message m;
m.size = 30;
printf("sizeof(int): %d\n",sizeof(int));
printf("sizeof(0x123456): %d\n",sizeof(0x123456));
printf("sizeof(Message): %d\n",sizeof(Message));
printf("sizeof(m): %d\n",sizeof(m));
}
While compiling this source with gcc I get the following warning, which I don't understand:
$ gcc sizeof.c
sizeof.c:5: warning: declaration does not declare anything
Line 5 refers to the enum line. I want that token in every Message, that I create. What am I doing wrong? What do I have to change to get rid of that warning?
My main contains several calls of sizeof(). When I run the program, you can see in the output that the integer has the size of four, the hex number has the size of 4, but the typedef struct Message has the size of 4, too:
$ ./a.out
sizeof(int): 4
sizeof(0x123456): 4
sizeof(Message): 4
sizeof(m): 4
That is very confusing to me. Why has Message the size of 4, although it contains an integer and an integer within an enum, each with the size of 4. If the sizeof(Message) would be at least 8, it would be logical to me.
But why is it only 4? How do I get the real size in Bytes of my Message? Or is this really the real size? If so, why?
Is there a difference in getting the size of a Message between C and C++?
An enumeration doesn't actually need any space, it's just a way for the compiler to recognize a set of literal numbers by a name.
You are not declaring anything with:
enum {token=0x123456};
Your declaration is similar to:
typedef struct {
int size;
int;
} Message;
If you declare your struct like this:
typedef struct {
int size;
enum {token=0x123456} e;
} Message;
There will be two fields, but e will not be initialized to anything. You need to set it manually for every instance: message.e=token.
The correct way to achieve what you want is, to use constructors in C++:
struct Message {
int size;
int token;
Message() : token(0x123456) {};
};
Or non-static data member initializers in C++11:
struct Message {
int size;
int token=0x123456;
};
There is no way to initialize field in struct declaration in C.
Line 5 does not declare any variable that is of type enum. So the compiler does the only thing it can do: ignore it.
If you want to create a member of that type in the struct, write something like
enum {token=0x123456} thetoken;
But be aware that this field can only have one valid value, is that what you want?
Edit:
Oh, and to answer your other question: I can't see a difference in output when compiling as C or C++. But there is a difference between how how you should write struct definitions.
typedef struct {
int size;
enum YouShouldDeclareAName {token=0x123456};
} Message;
your enum is a subclass/subtype of your Message struct, therefore bounds to Class and not object. Like a namespace. You do not create any variable with it.
Change it to:
typedef struct {
int size;
enum YouShouldDeclareAName {token=0x123456} token;
//or
YouShouldDeclareAName token2;
} Message;
You've defined a constant Message::token that's shared between all objects. Since it's shared, it doesn't count towards the size of a single object.
As the others answers note, you've declared an enumerated type, you just happened to do it inside a structure instead of at global scope. There's nothing to store, so it uses no memory.
Now if you were to declare an instance of your enumeration in that structure...
typedef struct {
int size;
enum {token=0x123456} e;
} Message;
int main(int argc, char * argv[])
{
Message m;
m.size = 30;
printf("sizeof(m): %d\n",sizeof(m));
}
sizeof(m): 8
Press any key to continue . . .
LINE 5:
enum {token=0x123456};
This line doesn't define any enum variable, its a declaration, because of this your compiler complains about line 5 saying its only a declaration.
proper usage should be:
enum {xyz=5} enum_variable_name;
Only then the compiler will allocate space for this.
Just like class, function, enum, static menber doesn't store in the object space!

C++ Trickery : output actual enum, not its value [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++: Print out enum value as text
Say I have an enumeration:
typedef enum MyEnum_
{
MY_ENUM_BLUE,
MY_ENUM_RED,
MY_ENUM_GREEN
} MyEnum;
And that I have a method that gets an "MyEnum" as parameter. I'd like write to log file the value of that MyEnum, but I don't want 0, 1 or 2 to appear there--- I'd like to output the actual enumeration string "MY_ENUM_xxxx", of course without a switch/case block..... and dealing with each value individually.
Is there some trickery or pattern, in c++ or using macros that would help me achieve that?
No need to typedef in c++
enum MyEnum_
{
MY_ENUM_BLUE,
MY_ENUM_RED,
MY_ENUM_GREEN
} MyEnum;
#define TOSTR(x) #x
const char *names[]={TOSTR(MY_ENUM_BLUE),
TOSTR(MY_ENUM_RED),
TOSTR(MY_ENUM_GREEN)};
int main(int argc, char *argv[])
{
MyEnum_ e=MY_ENUM_RED;
std::cout << names[e] << std::endl;
return 0;
}