delphi programming forums mysql charset mget recursive synonimos
free ventrilo servers hosting cs javascript delay python find in list
Back Forum New
abstract:

  It surprises me that this type of operator overloadind isn't available by default.
(btw, since the struct I am using is just an array of 4 bytes, there's no 'empty' bits whose randomness could possibly cause a memory compare of two equal structs to fail)
Any thoughts?


I have a struct defined (an array of 4 bytes).  Variables a and b are both of this same type of struct.  C or C++ will
not
accept this:
if (a == b) do something;
Besides for defining my own overloaded operator, is there any way you can set the compiler to know that they are of the same type and to accept the code above?  I would assume the compiler would produce much better code if it just knew they were of the same type, rather than me making an overloaded operator to do it.  It surprises me that this type of operator overloadind isn't available by default.
(btw, since the struct I am using is just an array of 4 bytes, there's no 'empty' bits whose randomness could possibly cause a memory compare of two equal structs to fail)
Any thoughts?

TOP

structs are stored as pointers to their data. so imho there is no way around overloading operators or defining a "compare()" function
for small structs, like 4 bytes, you could cast them to *(int*) and compare the result. but for bigger ones, .... ???
ps. are you Matthew´s brother? just curious...

TOP

memcmp(), perhaps?
memcmp
#include <memory.h>         Required only for function declarations
#include <string.h>        Use either STRING.H (for ANSI compatibility)
Syntax         int memcmp( const void *buf1, const void *buf2, size_t count );
Parameter        Description
buf1        First buffer
buf2        Second buffer
count        Number of characters
The memcmp and function compares the first count bytes of buf1 and buf2 and return a value indicating their relationship, as follows:
Value        Meaning
< 0        buf1 less than buf2
= 0        buf1 identical to buf2
> 0        buf1 greater than buf2

TOP

Thank you for your replies.
M.Hirsch: Yes, I am Matthew's brother.   I have to be honest that I did not realize that structs are stored as pointers to their data. One of the major things I dislike about C and its derivatives is that no one (manuals, tutorials, teachers, etc.) seems to explain exactly
what
is going on when they explain code like structs and multi-dimension arrays. I always like to know what is happening 'under the hood'.
Dereferencing a type cast to a 32-bit int would solve this particular problem... thanks. But, this doesn't solve the lack of a default overloaded operator for structs larger than 32-bits (or for those whose bits are all not used). I guess making a function or overloaded operator is the only way...
dwise1_aol: Thanks, memcmp would also work. As M.Hirsch has pointed out, since structs are pointers, you would have to make sure to deference them first, so you don't compare the pointers themselves.

TOP

abstract:

  It surprises me that this type of operator overloadind isn't available by default.
(btw, since the struct I am using is just an array of 4 bytes, there's no 'empty' bits whose randomness could possibly cause a memory compare of two equal structs to fail)
Any thoughts?



Originally posted by Jason Doucette

dwise1_aol
: Thanks, memcmp would also work. As M.Hirsch has pointed out, since structs are pointers, you would have to make sure to deference them first, so you don't compare the pointers themselves.
No need to dereference first, since memcmp takes pointers as its arguments.
I have always passed structs using the address operator; eg, memcmp(&struct_a,&struct_b,n).  I'll have to experiment with what happens if I just use the name.  Off-hand, I'm not sure that it would compile.

TOP

Both ways should work.  Saying that structs are stored as pointers to their data is a bit misleading.  Structs are not stored as pointers.  You can, and probably will, use a pointer to access them, but you don't have to.

TOP

Both ways do work.  For example, having declared a struct rec:
Code:
  1. void Report(struct rec *s);
  2.   struct rec A;
  3.   Report(&A);
Copy Code
or
Code:
  1. void Report(struct rec s);
  2.   struct rec A;
  3.   Report(A);
Copy Code
Both work.  But not:
Code:
  1. void Report(struct rec *s);
  2.   struct rec A;
  3.   Report(A);
Copy Code
For that, you will get an "incompatible type for argument" error.
However, all the library functions I've seen want you to pass them a struct pointer, so the first would be the prefered/more-conventional way.

TOP

dwise1_aol: Yes, you are right, memcmp takes pointers, so you don't have to deference a pointer first.  Since you have shown the structs are not pointers, then you would have to pass the address of the struct with the & operator as you have shown.
3dfxMM: Yes, you are also right, structs are not pointers (as dwise1_aol has proven).  Just because you will regularly use pointers to access them, or when you pass them into functions, it does not mean that structs themselves are pointers...
M.Hirsch: I would like to know why you said that strcuts are pointers?  I wish to know what you were getting at.  Perhaps it was the fact that they are
often
passed into functions as pointers?
I was under the impression that structs were not pointers.  Then you stated that they were, so I assumed that it was yet another detail that is skipped during most explanations of structs, and that they were simply a 'hidden' pointer like arrays (in which you don't have to dereference it, since the compiler takes care of that for you, hiding the fact that it is a pointer - which, I must say, is a horrible thing for any language).
Thanks for the response, guys!

TOP


Originally posted by Jason Doucette

M.Hirsch
: I would like to know why you said that strcuts are pointers?  I wish to know what you were getting at.  Perhaps it was the fact that they are
often
passed into functions as pointers?
I was under the impression that structs were not pointers.  Then you stated that they were, so I assumed that it was yet another detail that is skipped during most explanations of structs, and that they were simply a 'hidden' pointer like arrays (in which you don't have to dereference it, since the compiler takes care of that for you, hiding the fact that it is a pointer - which, I must say, is a horrible thing for any language).
I did yet another quick experiment in which I looked at the assembly listing generated by my previous examples -- gcc -S structs.c -- in order to compare their "thunk codes" (what I learned years ago in school as the term for the code that sets up for a function call).  Of course, I also had to dig back a long ways to remember how to read assembly.
The code generated by passing an address (eg, Report(&A); ) did a "load effective address" of the structure.  The code generated by passing the struct itself (eg, Report(A); ) actually pushed the contents of the structure onto the stack to pass the structure.
What immediately comes to mind is that exactly how the code that the compiler generates actually passes a structure is most likely implementation-dependent, which means that it depends on the compiler and operating environment rather than on the C language itself.  I suspect that some implementations do treat a struct name as a pointer while others (eg, MinGW port of gcc to Windows) do not.  Hirsch might have learned or worked on an implementation that did.

TOP

abstract:

  It surprises me that this type of operator overloadind isn't available by default.
(btw, since the struct I am using is just an array of 4 bytes, there's no 'empty' bits whose randomness could possibly cause a memory compare of two equal structs to fail)
Any thoughts?


I think the real difference we are seeing here is the difference between C and C++.  In C you cannot pass complex data types.  You must pass them by reference so compilers typically make allowances, i.e. the address of operator is assumed.  In C++ you can pass a pointer to the struct, a reference to the struct, or the struct itself.  In the first case, you explicitly reference the passed struct via a pointer.  In the second case, it is passed by reference but you treat it as a struct on the other end.  In the third case, it is passed directly on the stack and you treat it as a local variable.  The first two allow for changes to the original struct while the last one does not.

TOP

Back Forum