473,669 Members | 2,492 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

find index, given pointer to member

ike
Could you please give your opinion on the portability of this code?

/* -------- begin findindex.c -------- */

struct Foo { int junk0; };
struct Bar { int junk1; struct Foo foo; int junk2; };

int findindex(struc t Bar * bars, struct Foo * fooptr)
/* Pre:
* bars points to (the first element of) an array of Bar.
* fooptr points to the 'foo' member of an element of bars,
* i.e. fooptr == & bars[i].foo for some valid index i
* Returns:
* the actual value of i, as defined above.
*/
{
return ((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars;
}

/* -------- end findindex.c -------- */

Ike
Nov 14 '05 #1
11 2830
ik*@iae.nl wrote:
Could you please give your opinion on the portability of this code? /* -------- begin findindex.c -------- */ struct Foo { int junk0; };
struct Bar { int junk1; struct Foo foo; int junk2; }; int findindex(struc t Bar * bars, struct Foo * fooptr)
/* Pre:
* bars points to (the first element of) an array of Bar.
* fooptr points to the 'foo' member of an element of bars,
* i.e. fooptr == & bars[i].foo for some valid index i
* Returns:
* the actual value of i, as defined above.
*/
{
return ((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars;
}


Looks ok to me (as long as the arguments are what you tell). An alter-
native would be

return (struct Bar*)((char*)fo optr - offset_of(struc t Bar, foo)) - bars;

which avoids the (explicit) division. And did you think about returning
a size_t instead of an int (the result can't be negative or you called
it with invalid arguments)?
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@p hysik.fu-berlin.de
\______________ ____________ http://www.toerring.de
Nov 14 '05 #2
ik*@iae.nl wrote:
Could you please give your opinion on the portability of this code? struct Foo { int junk0; };
struct Bar { int junk1; struct Foo foo; int junk2; };

int findindex(struc t Bar * bars, struct Foo * fooptr)
/* Pre:
* bars points to (the first element of) an array of Bar.
* fooptr points to the 'foo' member of an element of bars,
* i.e. fooptr == & bars[i].foo for some valid index i
* Returns:
* the actual value of i, as defined above.
*/
{
return ((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars;
}


Ow, that's convoluted. AFAICT, it's not strictly portable, but you'd be
hard put to find an implementation where it wouldn't work. It would
require willful perversity of the implementor.

Richard
Nov 14 '05 #3
In message <3a************ *@uni-berlin.de>
Je***********@p hysik.fu-berlin.de wrote:
ik*@iae.nl wrote:
{
return ((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars;
}


Looks ok to me (as long as the arguments are what you tell). An alter-
native would be

return (struct Bar*)((char*)fo optr - offset_of(struc t Bar, foo)) - bars;

which avoids the (explicit) division.


It's worth noting that the implicit division by sizeof *bars in the latter
form is likely to be optimised better than the explicit one.

For an implicit division in a pointer subtraction, the compiler knows that
the result of the division must be exact, which allows a strength reduction
turning it into a simple modulo multiplication. Similar strength reductions
are possible for potentially non-exact divisions, but they are more
complicated.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #4
Richard Bos wrote:

ik*@iae.nl wrote:
Could you please give your opinion on the portability of this code?

struct Foo { int junk0; };
struct Bar { int junk1; struct Foo foo; int junk2; };

int findindex(struc t Bar * bars, struct Foo * fooptr)
/* Pre:
* bars points to (the first element of) an array of Bar.
* fooptr points to the 'foo' member of an element of bars,
* i.e. fooptr == & bars[i].foo for some valid index i
* Returns:
* the actual value of i, as defined above.
*/
{
return ((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars;
}


Ow, that's convoluted. AFAICT, it's not strictly portable,
but you'd be
hard put to find an implementation where it wouldn't work. It would
require willful perversity of the implementor.


Are you refering to the difference
exceding the range of ptrdiff_t?

--
pete
Nov 14 '05 #5
ike
Je***********@p hysik.fu-berlin.de wrote:
ik*@iae.nl wrote:
Could you please give your opinion on the portability of this code? struct Foo { int junk0; };
struct Bar { int junk1; struct Foo foo; int junk2; }; int findindex(struc t Bar * bars, struct Foo * fooptr)
/* Pre:
* bars points to (the first element of) an array of Bar.
* fooptr points to the 'foo' member of an element of bars,
* i.e. fooptr == & bars[i].foo for some valid index i
* Returns:
* the actual value of i, as defined above.
*/
{
return ((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars;
}
Looks ok to me (as long as the arguments are what you tell). An alter-
native would be return (struct Bar*)((char*)fo optr - offset_of(struc t Bar, foo)) - bars;
In fact that was one of the solutions I made up myself earlier, but
some compilers bark at the cast from a pointer type with loose alignment
requirements (here: char *) to a pointer type with stricter alignment
requirements (here: struct Bar *), and I wanted the code to compile
cleanly on all platforms.

<nitpick> s/offset_of/offsetof/ </nitpick>
<nitpick> offsetof() needs stddef.h </nitpick>
which avoids the (explicit) division. And did you think about returning
a size_t instead of an int (the result can't be negative or you called
it with invalid arguments)?


Yes I did, but I wanted to keep the posted example as minimal as possible.
Using size_t would have required "#include <stddef.h>".
Nov 14 '05 #6
ik*@iae.nl wrote:

Je***********@p hysik.fu-berlin.de wrote:
did you think about returning a size_t

Yes I did,
but I wanted to keep the posted example as minimal as possible.
Using size_t would have required "#include <stddef.h>".


But with your explanation included,
it winds up being less than minimal.

And with this question:
"Could you please give your opinion on the portability of this code?"
you knew that the size_t issue was going to come up.

--
pete
Nov 14 '05 #7
ike
pete <pf*****@mindsp ring.com> wrote:
ik*@iae.nl wrote:

Je***********@p hysik.fu-berlin.de wrote:
> did you think about returning a size_t
Yes I did,
but I wanted to keep the posted example as minimal as possible.
Using size_t would have required "#include <stddef.h>".
But with your explanation included,
it winds up being less than minimal.
And with this question:
"Could you please give your opinion on the portability of this code?"
you knew that the size_t issue was going to come up.


The portability question was about the return expression,
apparently I should have stated that more clearly.
The rest of the code was only added to produce a small compilable example.

Kind regards,
Ike
Nov 14 '05 #8
ik*@iae.nl wrote:

pete <pf*****@mindsp ring.com> wrote:
ik*@iae.nl wrote:

Je***********@p hysik.fu-berlin.de wrote:
> did you think about returning a size_t Yes I did,
but I wanted to keep the posted example as minimal as possible.
Using size_t would have required "#include <stddef.h>".

But with your explanation included,
it winds up being less than minimal.
And with this question:
"Could you please give your opinion on
the portability of this code?"
you knew that the size_t issue was going to come up.


The portability question was about the return expression,
apparently I should have stated that more clearly.
The rest of the code was only added to produce
a small compilable example.


The return expression
((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars
contains a subexpression
(char*)fooptr - (char*)&bars[0].foo
of type ptrdiff_t.

ptrdiff_t isn't guaranteed by the standard
to be big enough to be able to represent the difference
between two pointers.
In C89 there's not that much information available
to a program about the ptrdiff_t type.

My feeling from looking at the C89 and C99 standards, is that
the intention was for ptrdiff_t to either be larger than size_t
or at the very least, to be as big as the signed version of size_t,
but there's no guarantee like that in the standard.

Even if ptrdiff_t were always at least as
big as the signed version of size_t,
your ptrdiff_t expression is in a place where it might be required
to represent the whole range of size_t.

Here's what the standard says on the issue.
N869
6.5.6 Additive operators
[#9] When two pointers are subtracted, both shall point to
elements of the same array object, or one past the last
element of the array object; the result is the difference of
the subscripts of the two array elements. The size of the
result is implementation-defined, and its type (a signed
integer type) is ptrdiff_t defined in the <stddef.h> header.
If the result is not representable in an object of that
type, the behavior is undefined.

--
pete
Nov 14 '05 #9
pete <pf*****@mindsp ring.com> wrote:
Richard Bos wrote:

ik*@iae.nl wrote:
Could you please give your opinion on the portability of this code?

struct Foo { int junk0; };
struct Bar { int junk1; struct Foo foo; int junk2; };

int findindex(struc t Bar * bars, struct Foo * fooptr)
/* Pre:
* bars points to (the first element of) an array of Bar.
* fooptr points to the 'foo' member of an element of bars,
* i.e. fooptr == & bars[i].foo for some valid index i
* Returns:
* the actual value of i, as defined above.
*/
{
return ((char*)fooptr - (char*)&bars[0].foo) / sizeof *bars;
}


Ow, that's convoluted. AFAICT, it's not strictly portable,
but you'd be
hard put to find an implementation where it wouldn't work. It would
require willful perversity of the implementor.


Are you refering to the difference exceding the range of ptrdiff_t?


No, I'm referring to the comparison of two pointers which do not point
to the same (struct Foo) object. AFAICT, it would be legal if the
pointers were struct Bar pointers, since then they'd be pointers to
members of an array. Now they're pointers to members of disjunct
objects. I would be very surprised at an implementation where this were
an actual problem, of course.

Richard
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

97
27773
by: s | last post by:
Can I do this: #define MYSTRING "ABC" .. .. .. char mychar = MYSTRING; .. .. ..
2
2070
by: Vince | last post by:
I have a very specific problem to solve but I cannot find a data structure for it. I don't know if I am posting on the good newsgroup but I cannot find a software.design group. I would like to declare a smart structure initialized via a XML file. The goal of this structure is to store data from a smart card. My XML file describes the file structure of my smart card. On a smart card file are identified by number(sfid) and not by their...
4
2340
by: Deniz Bahar | last post by:
Hello all, Often times programs in C have arrays used as buffers and shared among different sections of code. The need arises to have position indicators to point to different parts of an array (example: point to top of stack). Before I even got K&R2 I used to just define extra pointers to types equal to the element type of the arrays to act as indicators. Now flipping through K&R2, I see they use int variables to act as "offsets." ...
2
1878
by: Martin v. Löwis | last post by:
I've been working on PEP 353 for some time now. Please comment, in particular if you are using 64-bit systems. Regards, Martin PEP: 353 Title: Using ssize_t as the index type Version: $Revision: 42333 $
13
5037
by: Steve Edwards | last post by:
Hi, Given a map: typedef map<long, string, greater<long> > mapOfFreq; Is there a quicker way to find the rank (i.e. index) of the elememt that has the long value of x? At the moment I'm iterating through the map and keeping count of when I hit it.
16
4454
by: Petrakid | last post by:
Hey, I have a task to complete. I am trying to figure out the best way, in C++ to determine the following. There is this farm with pigs and chickens. Only the legs of the pigs and chickens look exactly the same, so for a short person to determine how many possible pigs and how many possible chickens, all they can do is count the total legs of the two. - Chickens seem to always run around in groups of 3 - Pigs seem to always clump...
11
1950
by: desktop | last post by:
How do I find the last element in the list numsx defined below? int* myfind(int* arr_start, int* arr_end, int& s) { int not_found = 666; int* result = &not_found; while (arr_start != arr_end){ if (*(arr_start) == s) { result = arr_start;
6
1703
by: chris.kemmerer | last post by:
I am having a problem with templates and I hope someone here can help. I am writing a library that accepts data packets, parses them and saves the information for later use. One member of the packet is an enumeration that says what type of data the packet contains (int, char, etc.). I have created classes similar to below. The problem I am having is in trying to access the derived class given only a pointer to the base class. I know that...
2
2068
by: everly | last post by:
Hi, I'm helping my friends band and making their MySpace. I messed something up and I can't figure out what it is. Everything is all out of whack on the bottom half of the page. The comments shouldn't be on the left hand side. Help please! Thanks. ____________________________________________________- <style type="text/css"> { Background Properties } table, tr, td { background-color:transparent; border:none; border-width:0;} body {...
0
8465
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8895
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8588
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8658
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7407
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5682
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4386
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2797
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2032
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.