|
I think you're making it too complicated:
struct ESDID
{
char c[4];
bool operator<(const ESDID& other) const
{
return c[0] < other.c[0] && c[1] < other.c[1] &&
c[2] < other.c[2] && c[3] < other.c[3];
}
}
struct usingrange
{
ESDID esdid;
int start;
int end;
bool operator<(const usingrange& other) const
{
return esdid < other.esdid && start < other.start &&
end < other.end;
}
}
I've used && and < because you do not want operator<() to return true for two different objects when you swap them around.
|
|
|
|
|
just tried it that did it thank you
|
|
|
|
|
hi
I am getting a read access error in xtree line 1607. This after i have inserted 4,527 map entries successfully I did a call to map::maxsize using a unsigned integer and it came up with a number 0x76767676 I dont think memory is the issue as I have 64 gb machine
I bypassed the entry just to see if there was something wrong with that entry and go an error on the next as well
here is the microsoft code I underlined the while statement with the issue intellesense is giving the message _Trnode was 0x40D51F000040.
any guidence who i shoud go about debugging would be appreciated
template <class _Keyty>
_Tree_find_result<_Nodeptr> _Find_lower_bound(const _Keyty& _Keyval) const {
const auto _Scary = _Get_scary();
_Tree_find_result<_Nodeptr> _Result{{_Scary->_Myhead->_Parent, _Tree_child::_Right}, _Scary->_Myhead};
_Nodeptr _Trynode = _Result._Location._Parent;
while (!_Trynode->_Isnil) {
_Result._Location._Parent = _Trynode;
if (_DEBUG_LT_PRED(_Getcomp(), _Traits::_Kfn(_Trynode->_Myval), _Keyval)) {
_Result._Location._Child = _Tree_child::_Right;
_Trynode = _Trynode->_Right;
} else {
_Result._Location._Child = _Tree_child::_Left;
_Result._Bound = _Trynode;
_Trynode = _Trynode->_Left;
}
}
|
|
|
|
|
I had a buffer that was way too small it overlayed data inluding the pointer to the map class
thanks
|
|
|
|
|
Hi
my overloaded operator are in my header so I make a breakpoint watching them being invoked except for the = operator hope some can tell me why
i'll post
first type of struct using range
;
struct usingrange
{
ESDID esdid;
int start;
int end;
uint32_t operator=(const BYTE z[4])
{
return ((z[0] << 24) | (z[1] << 16) | (z[2] << 8) | z[3]);
};
bool operator<(const usingrange x) const {
if (esdid < x.esdid) return esdid < x.esdid;
if (start < x.start) return start < x.start; if (end < x.end) return end < x.end;
};
};
next my code with the = operator the lvalue is member of using range I would think that would casue invocation of my overloaded operator
usingrange using_range{ usingpoint->usingesdid };
using_range.start = (BYTE &)usingpoint->statement;
using_range.end = (BYTE &)usingpoint->laststatement;
|
|
|
|
|
Again, not sure which one of the 3 statements you would expect to invoke the assignment operator. The first one:
usingrange using_range{ usingpoint->usingesdid }; is a declaration that invokes a constructor. As you don't have a constructor, the compiler creates a default one.
The second and the third:
using_range.start = (BYTE &)usingpoint->statement;
using_range.end = (BYTE &)usingpoint->laststatement; are simply integer assignments.
If you would want to invoke the assignment operator you would need to write something like
usingrange using_range2;
using_range2 = using_range;
Mircea
|
|
|
|
|
these two the lvalue is a int and a member of using range the rvalue is of type BYTE [4] ? I am sure I am not understanding something ?
using_range.start = *usingpoint->statement;
using_range.end = *usingpoint->laststatement;
|
|
|
|
|
If statement is BYTE[4] , usingpoint->statement is a pointer to a BYTE value. So *usingpoint->laststatement is the content of the first byte. It can be assigned to an integer without any problem. That's probably not what you want but that's what the compiler understood.
The assignment operator that you defined is for assigning the WHOLE structure. It doesn't apply to individual members.
Mircea
|
|
|
|
|
you are right I saw that in that disassembly however I made a breakpoint at "int operator+..." and it never got invoked probably because as you said the rvalue is BYTE while in the operator= parameter it BYTE z[4]; when I have the code
using_range.start = usingpoint->statement; I got an error message from intellsense saying cannt assign int to BYTE *
|
|
|
|
|
I think you misunderstood the functioning of overloaded operators. I'll try to explain but it's best if you check with a proper manual. I'm not a particularly good teacher
If you have something like:
struct A {
char ch;
long l;
};
struct B {
int i;
char c;
};
A a;
B b;
If you write an assignment:
a = b;
The compiler will complain that it doesn't know how to assign a B to an A. Kind of an apples and oranges problem.
However you can write:
a.l = b.i;
a.ch = b.c; because those are standard types and compiler knows how to perform those assignments without needing a user defined assignment operator.
Now we add a user defined assignment operator:
struct A {
char ch;
long l;
int operator =(B& rhs) {l = rhs.i; ch = rhs.c; return 1;}
};
After that we can write:
a = b; and the compiler will know how to do the assignment.
You can have many such assignment operators. For instance you might add another one to assign an A to another A:
struct A {
char ch;
long l;
int operator =(B& rhs) {l = rhs.i; ch = rhs.c; return 1;}
int operator =(A& rhs) {l = rhs.l; ch = rhs.ch; return 1}
};
The assignment operator that takes an object of the same kind on the right hand side is called "principal assignment operator".
Note however that we cannot "chain" the assignment operator. If we write:
A a1;
a1 = a = b; we will get an error because the result of
a = b is an int and cannot be assigned to an A. To respect the conventions we would have to change the signature of the principal assignment operator:
struct A {
char ch;
long l;
int operator =(const B& rhs) {l = rhs.i; ch = rhs.c; return 1;}
A& operator =(const A& rhs) {l = rhs.l; ch = rhs.ch; return *this;}
};
Note that I also made the right hand side a reference to a const.
I hope you will find useful my little lecture on assignment operators but, again, best would be to check with a real manual.
Mircea
|
|
|
|
|
thanks beginning to see there is not a way to do what I want with operator overloading
|
|
|
|
|
Hi
I am still having problems with map::insert
Here is my data
struct usingx
{
unsigned char rectype;
#define using 0
#define pop 0x20
#define push 0x40
#define drop 0x80
unsigned char usingflag
#define oridinaryusing 0
#define labeledusing 0x10
#define depedentusing 0x20
#define labeldependentusing 0x30
; ESDID locesdid;
BYTE statement[4];
BYTE location[4];
BYTE usingvalue[4];
BYTE laststatement[4];
ESDID usingesdid;
unsigned char registerx;
BYTE displacement[2];
BYTE reservedz;
BYTE usingrange[4];
BYTE reservedu[2];
BYTE labeloffset[4];
BYTE labelength[4];
char* labelx;
};
Here is the key that I am using the start and end variable are big endian so I have to convert it and overloaded the = operator;
struct usingrange
{
ESDID esdid;
int start;
int end;
int operator=(BYTE z[4]) { return _byteswap_ulong((int)z[4]); };
bool operator<(const usingrange x) const {
if (esdid < x.esdid) return esdid < x.esdid;
if (start < x.start) return start < x.start; if (end < x.end) return end < x.end;
};
here is the code using the map::insert
usingrange using_range{ usingpoint->usingesdid };
using_range.start = *usingpoint->statement;
using_range.end = *usingpoint->laststatement;
procpointer->usingptr->insert({ using_range,*usingpoint });
break;
I made breakpoints on the operator= code and thought when I stepped into it with the vs debugger it would trace it but it didnt
both start and end ended up zeros
dont know why ?
|
|
|
|
|
The line
usingrange using_range{ usingpoint->usingesdid };
does not invoke your assignment operator. This is a constructor and it will just copy the argument. Not sure where you expected the assignment to be invoked.
I would replace the assignments with a constructor similar to this:
struct usingrange
{
usingrange(usingx& x) {
esdid = byte_swap(x.usingesdid;
start = x.statement;
end = x.laststatement;
}
ESDID esdid;
int start;
int end;
As a comment, your comparison operator is suboptimal and incomplete. I’m surprised you didn’t get a warning that not all control paths return a value.
Mircea
|
|
|
|
|
I understand at this point I am trying to get the =operator overload working I think it’s only referencing the first byte as opposed to 4 bytes
Thought if I cast it it would work but didn’t going to try to move it to a int
|
|
|
|
|
Message Closed
modified 18-Dec-22 13:49pm.
|
|
|
|
|
You can simplify to:
auto ret = procpointer->extsymcollector->insert({exsympointer->SYMESDID, *exsympointer})
ForNow wrote: my code does NOT complie
What compiler to you use? what message to you get?
Mircea
|
|
|
|
|
That worked with iterator thanks these overloads drive me crazy 🙂
|
|
|
|
|
when I specify a return of a iterator
I get no suitable conversion
map<uint32_t, extsymbol> ::iterator extsymiter;
extsympointer = procpointer->extsymcollector->insert({exsympointer->SYMESDID, * exsympointer });
|
|
|
|
|
std::map::insert returns a pair. Nothing you can do about that.
Your code should look like:
map<uint32_t, extsymbol> ::iterator extsymiter;
auto ret = procpointer->extsymcollector->insert({exsympointer->SYMESDID, * exsympointer });
if (ret.second)
extsymiter = ret.first;
else
If you don't care if the element was there or not, you can just skip the if .
Mircea
|
|
|
|
|
thanks, I tried that
BTW I looked at the value of the iterator in storage and seems it prefixes my data with a int with the value of the entry number
Thank you again
|
|
|
|
|
Hi Mainframe data big endian which I am trying to typedef 4 bytes I would rather not do it as int
I tried the following typedef char ESDID[4] where ESDID would represent 4 bytes
I also have this type ESDID in structure and would like to use it as a key
for example
struct syminfo
{
unsigned char recordtype;
unsigned char recordtypeflag;
ESDID symesdid;
BYTE seclen[4];
ESDID eseclen;
char* symname;
};
I am getting all sort of comple errors when I map it
syminfo* exsympointer = (syminfo*)procpointer->buffer;
procpointer->extsymcollector.insert(std::pair<ESDID, syminfo>(exsympointer->symesdid, *exsympointer));
The map is define as such
map<ESDID, syminfo> extsymcollector;
I think thesee aerror are from the way I tried to typdef ESDID if also tried to set as an struct type
struct ESDID
{
char x[4];
};
either way I get errors
|
|
|
|
|
But you need the values of ESDID characters as key for the map.
something like this could do the trick
struct ESDID
{
char c[4];
uint32_t operator()(){return ((c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]); };
};
map <uint32_t, syminfo> m;
syminfo s1;
m.insert( pair<uint32_t, syminfo>(s1.symesdid(), s1) );
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
A few questions first of I am not on your level of C++ but i am getting there
so my first question is anytime you code a key as a structure you need code to tell it how to handle, format, compare that key ? is that right ?
second my data is big edian so DC F'10' lays out in storage 00000000 00000000 00000000 0000000A so the code shifts thngs back to little edian
as int x = 10 would be A0000000 00000000 00000000 00000000
your map statement below the structure why can it not be map <esdid, syminfo=""> m;
|
|
|
|
|
Quote: so my first question is anytime you code a key as a structure you need code to tell it how to handle, format, compare that key ? is that right ?
Generally speaking, you haven't. However, in your scenario, you have to, because the key you need is the value stored inside the characters, not the reference to the struct.
Quote: second my data is big edian so DC F'10' lays out in storage 00000000 00000000 00000000 0000000A so the code shifts thngs back to little edian
as int x = 10 would be A0000000 00000000 00000000 00000000
Kind of that. Note you actually don't even need the key being big-endian.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
Ok thank you again I am at work now I will compile it afterwards I have another map with a key made up of few elements in a structure
Had compile errors but I think if I do what you just did insert code in the the structure with a for lack of a better term dummy in-line call in the structure with the operator()() {}; I may be able to straighten it out a lot of this code I can use on the z/os mainframe so I am hoping outside of a few #ifdef _MSVC_ for the big Edian to little Edian conversion it will compile with the XL C\C++ compiler it too has a STL library thank you again
|
|
|
|