Can somebody explain why pp1 compiles, but pp2 does not?
I suppose it has something to do with the union and that the compiler will try to fit everything inbetween { } into buffer8 instead of DATA?
#include <iostream>
using namespace std;
union PassFilterValues
{
struct DATA
{
int32_t a;
int32_t b;
int32_t c;
int32_t k;
} data;
uint8_t buffer8[sizeof(DATA)];
};
union PassFilterDynamic
{
struct DATA
{
PassFilterValues lowFilter;
PassFilterValues highFilter;
} data;
uint8_t buffer8[sizeof(DATA)];
};
#define PASSFILTER_OFF {0,1,2,3}
int main() {
PassFilterDynamic pp1 = {((PassFilterValues)PASSFILTER_OFF), ((PassFilterValues)PASSFILTER_OFF)};
PassFilterDynamic pp2 = {PASSFILTER_OFF, PASSFILTER_OFF};
return 0;
}
feel free to try here: http://ideone.com/XYhfIi
Related
I have two types of events with associated values such as:
struct EventRequest
{
char EventType;
int RetryCount;
} ER;
struct EventStatus
{
char EventType;
char StatusType;
short RetryCount;
} ES;
I want to push the above structs onto one single queue/stack such as:
queue<typedef>q;
q.push(ER);
q.push(ES);
q.push(ER):
.
.
.
How can I do that?
One solution to this would be polymorphism: both structs inheriting from a common base class. However, that implies an "is-a" relationship that may not exist and would make your code awkward and harder to understand. With that in mind, another solution to this (since C++ 17) would be std::variant.
#include <queue>
#include <variant>
struct EventRequest {
char EventType;
int RetryCount;
} ER;
struct EventStatus {
char EventType;
char StatusType;
short RetryCount;
} ES;
int main() {
std::queue<std::variant<EventRequest, EventStatus>> q;
q.push(ER);
q.push(ES);
return 0;
}
There are several solution to that problem:
Make all strutures to inherit from a same base interface and use smart pointers.
Use unions (old-style)
For this example, I am going to show how to use std::variant
#include <variant>
#include <queue>
struct EventRequest
{
char EventType;
int RetryCount;
};
struct EventStatus
{
char EventType;
char StatusType;
short RetryCount;
};
using AnyEvent = std::variant<EventRequest, EventStatus>;
int main()
{
std::queue<AnyEvent> event;
event.push(EventRequest());
event.push(EventStatus());
return 0;
}
Run this code here:
https://onlinegdb.com/D17aVXA1K
I've got some trouble in allocating (::operator new) the declared structs inside an class, at its method, as getting an non-nub-readable error:
error: cannot convert 'Automata::state*' to 'state*' in assignment
\
I have tried removing the "Automata::" declaration, placing "this->" and other random things, no success. Follows an example code;
#include <iostream>
#include <new>
class Automata{
public:
struct quintuple{
struct state *stateStr = NULL;
int stateSize = 0;
};
struct state{
struct symbol *symbolStr = NULL;
};
struct symbol{
char *state = NULL;
int stateSize = 0;
};
struct quintuple quintupleStr;
//Functions
void quintuple(int stateValidCounter);
};
void Automata::quintuple(int stateValidCounter){
this->quintupleStr.stateStr = (struct Automata::state *) ::operator new(sizeof(struct Automata::state) * stateValidCounter);
return;
}
int main(){
Automata automata;
automata.quintuple(5);
return 0;
}
/*
g++ -std=c++11 example.cpp -o example.out
example.cpp: In member function 'void Automata::quintuple(int)':
example.cpp:23:30: error: cannot convert 'Automata::state*' to 'state*' in assignment
this->quintupleStr.stateStr = (struct Automata::state *) ::operator new(sizeof(struct Automata::state) * stateValidCounter);
^
*/
Thank you for the attention.
Well, to be honest this is an sad tiredness event.
I would like to accept the #Passer By if he answers at.
The answer is simple as #Passer By comment at main section.
Be the code
#include <iostream>
#include <new>
class Automata{
public:
struct quintuple{
struct state *stateStr = NULL;
int stateSize = 0;
};
struct state{....};
struct quintuple quintupleStr;
//Functions
void quintuple(int stateValidCounter);
};
void Automata::quintuple(int stateValidCounter){
this->quintupleStr.stateStr = (struct Automata::state *) ::operator new(sizeof(struct Automata::state) * stateValidCounter);
return;
}
int main(){
Automata automata;
automata.quintuple(5);
return 0;
}
simply switch the struct code position..
class Automata{
public:
struct state{....};
struct quintuple{
struct state *stateStr = NULL;
int stateSize = 0;
};
struct quintuple quintupleStr;
....;
};
I still think the compiler error is a little misleading
The Problem is that variables loose their values.
The variables selectable_values_array and searched_array_size contain the correct values while inside the initialisation of the find_number::find_number.
But when the find_closest object is called the variables are containing
values like -28 and 4214247.
As a logical consequence the samplerate_return returns just garbage.
So what am i missing here ?
Is there a method of safely passing a variable/values inside a class ?
Edit: Added the reduced MyClass and main.
#include "MyClass.h"
int main()
{
int32_t samplerate_return = 0;
int32_t samplerate_request = 7;
MyClass ADC_1 ();
while(1) {
samplerate_return = ADC_1.select(samplerate_request);
}
}
The first Class:
#ifndef MyClass_H
#define MyClass_H
#include "find_number.h"
class MyClass
{
public:
MyClass();
int32_t select(int32_t the_searched_number);
int32_t the_selected_number;
private:
int32_t Integer_array[];
int32_t Numbers_in_Integer_array;
bool init();
find_number MyNumber;
};
And the MyClass.cpp
#include "MyClass.h"
MyClass::MyClass()
{
init();
find_number MyNumber;
}
bool MyClass::init()
{
int32_t Integer_array[] = {2,5,10};
Numbers_in_Integer_array = (sizeof(Integer_array)/sizeof(*Integer_array));
find_number MyNumber (Integer_array,Numbers_in_Integer_array);
return 0;
}
int32_t MyClass::select(int32_t the_searched_number)
{
the_selected_number = MyNumber.find_closest(the_searched_number);
return the_selected_number;
}
This is the header file of the "Find_Numbers" class:
#ifndef find_number_h
#define find_number_h
class find_number
{
public:
//Constructor:
find_number(int32_t *selectable_values,int32_t cells_in_array);
find_number(); // = default;
//Class Objects:
int32_t find_closest(int32_t target_value);
private:
int32_t searched_array_size;
int32_t *selectable_values_array;
};
#endif
And the corresponding find_numbers.cpp
#include "find_number.h"
find_number::find_number(int32_t *selectable_values, int32_t cells_in_array)
{
selectable_values_array = selectable_values;
searched_array_size = cells_in_array;
}
find_number::find_number() {};
int32_t find_number::find_closest(int32_t target_value)
{
int32_t difference = abs( target_value - *selectable_values_array);
int32_t closest_integer = selectable_values_array[0];
// calculating stuff
return closest_integer;
}
i wrote this code to optimize the struct to be aligned for array usage :
#include <iostream>
#include <stdlib.h>
struct Foo {
int z;
char c;
} __attribute__((packed));
struct FooForArray
{
Foo f;
char aligner[sizeof(int)-sizeof(Foo)%sizeof(int)]; // fill the missing bytes with this dump array for aligment
};
int main()
{
std::cout<<"sizeof AlignedFoo = "<<sizeof(FooForArray)<<std::endl;
std::cout<<"sizeof Foo = "<<sizeof(Foo)<<std::endl;
system("pause");
}
output :
sizeof AlignedFoo = 8
sizeof Foo = 5
Press any key to continue...
I think that most compilers will do that by default , but im doing this for learining , is it a good approach ?
I'm new to C++/CLI and are having a hard time with Lists.
I have a structure
#using namespace System::Collections::Generic
struct myStruct {
unsigned int A ;
int B; };
and i want to create a list with mystructs
List<myStruct> myList;
But that seems not to work, Visual Studio says
"myStruct is not a valid generic Argument", but why is that so?
And how can i make this structure a "valid generic argument"?
#include <List>
struct myStruct {
unsigned int A ;
int B;
};
std::list<myStruct> myList;
int main(void) {
return 0;
}