473,811 Members | 3,248 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

offsetof() macro

Hi,

Can somebody please help me grok the offsetof() macro?

I've found an explanation on
http://www.embedded.com/shared/print...cleID=18312031
but I'm afraid it still doesn't make sense to me.

The sticking point seems to be:

((s *)0) takes the integer zero and casts it as a pointer to s.

To my untrained eye that would basically result in a null pointer. Does
this expression result in some special behaviour or am I missing
something?

Thanks.

Simon

--
"Being a social outcast helps you stay concentrated on the really important
things, like thinking and hacking." - Eric S. Raymond

Nov 15 '05
44 3761
DevarajA <no@spam.com> writes:
[...]
Another thing.. looking into stddef.h I've seen that for C, NULL it is
defined as ((void*)0). The standard specifies that plain 0 is already
a null pointer constant. So why that cast? Maybe this is the last
stupid question for today :-)


No, looking into the stddef.h header for your implementation tells you
how your implementation defines NULL. Another implementation could
define it as 0.

The standard says that a null pointer constant is "An integer constant
expression with the value 0, or such an expression cast to type void *",
and that NULL is a macro that "expands to an implementation-defined
null pointer constant".

One advantage of defining NULL as ((void*)0) rather than as 0 is that
it can catch some errors. A constant 0, though it's a null pointer
constant, can also be used in a non-pointer context; ((void*)0)
cannot. For example, I've seen code that incorrectly uses NULL to
denote a null character:
char s[50];
s[0] = NULL;
If NULL is defined as 0, this won't be diagnosed. If it's defined as
((void*)0), it will be.

Please ignore the remainder of this message.

There's actually some doubt about whether ((void*)0) is a legal
definition for NULL. The standard says that a constant 0 cast to
void* is a null pointer constant. It doesn't say that a constant 0
cast to void* *and enclosed in parentheses* is a null pointer
constant. C99 6.5.1 says a parenthesized expression "is an lvalue, a
function designator, or a void expression if the unparenthesized
expression is, respectively, an lvalue, a function designator, or a
void expression"; it doesn't say that a parenthesized expression is a
null pointer constant if the unparenthesized expression is a null
pointer constant.

This is nothing more than a minor glitch in the wording of the
standard, of no real significance either to programmers or to
implementers.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #21
DevarajA wrote:

<snip>
Another thing.. looking into stddef.h I've seen that for C, NULL it is
defined as ((void*)0). The standard specifies that plain 0 is already a
null pointer constant. So why that cast? Maybe this is the last stupid
question for today :-)


The C standard allows the implementation to include the case, and the
reason that some implementations do so is to prevent you from using NULL
in an integer context. So on your implementation the following are all
constraint violations because pointers are not automatically converted
to numbers:

char c = NULL;
int i = NULL;
float f = NULL;
double d = NULL;

However, on an implementation where NULL is defined as plain 0 (which
the standard allows) all of the above are legal even though to a human
reader they don't make sense.

One reason people do mistakenly assign NULL to char variables (or
elements of char arrays) is because the ASCII character set (which C
does not mandate) calls character '\0' NUL and the C standard I believe
calls it a null character, so it is easy to get it confused with NULL.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #22
In article <q9************ *************** *****@4ax.com>,
Irrwahn Grausewitz <ir*******@free net.de> wrote:
Depends on the implementation, yours happen to use the above
definition, another might define NULL as (0) or even
((void *)('9'-'4'-'5')).


That would only be equivilent to 0 in the rather unusual case
that the representation of the digits started from 0 instead of
(e.g.) ASCII's 48.

Perhaps you meant ((void *)('9'-'4'-5))

--
'The short version of what Walter said is "You have asked a question
which has no useful answer, please reconsider the nature of the
problem you wish to solve".' -- Tony Mantler
Nov 15 '05 #23
Irrwahn Grausewitz wrote:

DevarajA <no@spam.com> wrote:

[...]
Maybe this is the last stupid
question for today :-)


There are no stupid questions, only stupid answers. :-)


You've obviously never hung around ASR and ATSR, have you? They'll give
you plently of "stupid question" examples. :-)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer .h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th***** ********@gmail. com>
Nov 15 '05 #24
DevarajA wrote:
[...]
Another thing.. looking into stddef.h I've seen that for C, NULL it is
defined as ((void*)0). The standard specifies that plain 0 is already a
null pointer constant. So why that cast? Maybe this is the last stupid
question for today :-)


Probably to explicitly make it a pointer.

That, and to give warnings when someone does:

char *pt;
...
while ( *pt != NULL )
...

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer .h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th***** ********@gmail. com>
Nov 15 '05 #25
ro******@ibd.nr c-cnrc.gc.ca (Walter Roberson) wrote:
In article <q9************ *************** *****@4ax.com>,
Irrwahn Grausewitz <ir*******@free net.de> wrote:
Depends on the implementation, yours happen to use the above
definition, another might define NULL as (0) or even
((void *)('9'-'4'-'5')).


That would only be equivilent to 0 in the rather unusual case
that the representation of the digits started from 0 instead of
(e.g.) ASCII's 48.

Perhaps you meant ((void *)('9'-'4'-5))


Umm... something like that... brain fart on my side...
me dumba, he he. :)

Thanks for pointing out & best regards
--
Irrwahn Grausewitz (ir*******@free net.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc frequent answers: http://benpfaff.org/writings/clc.
Nov 15 '05 #26
On Thu, 08 Sep 2005 15:11:27 +0000, Simon Morgan wrote:
Can somebody please help me grok the offsetof() macro?


Thank you all for the excellent explanations, they were most helpful.

--
"Being a social outcast helps you stay concentrated on the really important
things, like thinking and hacking." - Eric S. Raymond

Nov 15 '05 #27
Keith Thompson <ks***@mib.or g> writes:
DevarajA <no@spam.com> writes:
Keith Thompson ha scritto: [...]
A "null pointer" and a "null pointer constant" are two different
things. A null pointer constant is a construct that can appear in
C source code. A null pointer is a pointer value that can occur
during execution time. An integer constant 0 is a valid null
pointer constant. If you assign a null pointer constant to a
pointer object, that object's value at execution time will be a
null pointer. The execution-time representation of a null pointer
may or may not be all-bits-zero. (If a null pointer has a
representation other than all-bits-zero, it's up to the compiler to
do whatever conversion might be necessary.) The macro NULL expands
to a null pointer constant. You cannot legally redefine NULL
yourself. Your compiler might let you get away with it, but
there's absolutely no reason to do so.


Then using NULL is the same as using 0? So why in C many people use
NULL? Is that to avoid portability problems (in the case of a weird
non-standard implementation that has the null ptr const !=0)?


The advantage of using NULL is documentation. It makes it obvious
that what's intended is a pointer value, not an integer value.

For example:

a = 0;
b = 0.0;
c = '\0';
d = NULL;

You can tell even without looking at the declarations (assuming a sane
programmer) that a is an integer, b is a floating-point variable, c is
a character, and d is a pointer.


A complaint I have about NULL is that NULL isn't guaranteed to be
a pointer. Supplying NULL as a trailing argument (corresponding
to a post-ellipsis parameter), for example, isn't guaranteed to
pass a pointer rather than an int 0. It would be nice if the
Standard were changed to fix this.
[snip] The current confusing situation is, I think, a remnant of the early
days of C when it was assumed that a null pointer *was* all-bits-zero,
and even non-zero integer constants were commonly used as pointers.


Perhaps partly, but there's another factor that may play a larger
role here. C deliberately proclaimed null pointers as zero and
non-null pointers as non-zero, so that they would work nicely
with if's and while's. People who learned C later seem to like
explicit comparisons (whether to NULL or 0); "old timers" are
more used to seeing things like

if(p) ...
if(!p) ...

and may even prefer them. For these forms, it's convenient to
think of null pointers as being all-bits-zero, even if in the
back of the mind it's known not to always be true.
Nov 15 '05 #28
Keith Thompson <ks***@mib.or g> writes:
There's actually some doubt about whether ((void*)0) is a legal
definition for NULL. The standard says that a constant 0 cast to
void* is a null pointer constant. It doesn't say that a constant 0
cast to void* *and enclosed in parentheses* is a null pointer
constant. C99 6.5.1 says a parenthesized expression "is an lvalue, a
function designator, or a void expression if the unparenthesized
expression is, respectively, an lvalue, a function designator, or a
void expression"; it doesn't say that a parenthesized expression is a
null pointer constant if the unparenthesized expression is a null
pointer constant.


Whatever NULL is defined as seems like it must be a null pointer
constant, by definition. Per 7.17 p3, NULL "expands to an
implementation-defined null pointer constant". So even if we had

#define NULL the rain in Spain falls mainly on the plain

it would be (defined by the implementation as) a null pointer
constant. It's just up to the other parts of the implementation
to insure that it behaves as one.

Is it true that, except for function pointers, it's unnecessary
to have '(void*) <constant-zero-expression>' be defined as a
null pointer constant?
Nov 15 '05 #29
Tim Rentsch <tx*@alumnus.ca ltech.edu> wrote:
Whatever NULL is defined as seems like it must be a null pointer
constant, by definition. Per 7.17 p3, NULL "expands to an
implementati on-defined null pointer constant". So even if we had

#define NULL the rain in Spain falls mainly on the plain

it would be (defined by the implementation as) a null pointer
constant. It's just up to the other parts of the implementation
to insure that it behaves as one.
IOW: the implementation has to take care that
the rain in Spain falls mainly on the plain
is treated as an integer constant expression with the value 0,
possibly cast to void * (see below). Ugly, but IMHO feasible.
But ugly. Did I already mention ugly?
Is it true that, except for function pointers, it's unnecessary
to have '(void*) <constant-zero-expression>' be defined as a
null pointer constant?


In which aspect are function pointers different? Consider:

ISO/IEC 9899:1999 (E)
6.3.2.3p3
An integer constant expression with the value 0, or such an
expression cast to type void *, is called a null pointer constant.
If a null pointer constant is converted to a pointer type, the
resulting pointer, called a null pointer, is guaranteed to compare
unequal to a pointer to any object or function.

6.5.16.1
1 One of the following shall hold:
[...]
— the left operand is a pointer and the right is a null pointer
constant
[...]
2 In simple assignment (=), the value of the right operand is
converted to the type of the assignment expression and replaces the
value stored in the object designated by the left operand.

Did I miss anything important?

Best Regards
--
Irrwahn Grausewitz (ir*******@free net.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc frequent answers: http://benpfaff.org/writings/clc
Nov 15 '05 #30

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

Similar topics

5
6348
by: Hiroki Horiuchi | last post by:
Hello. I wrote a program, but g++ warns a.c:11: warning: invalid access to non-static data member `A::y' of NULL object a.c:11: warning: (perhaps the `offsetof' macro was used incorrectly) The program is like below. class A {
9
2970
by: Exits Funnel | last post by:
Consider this code which is a very trimmed down version of some I've inherited and am trying to port from windows to g++: //Begin test1.cpp class foo { int i; int j; }; class bar { bar (int foo::* dataMember) :offsetof (foo, *dataMember) //Call this Line (A)
6
2205
by: Arthur J. O'Dwyer | last post by:
As far as I know, C89/C90 did not contain the now-standard offsetof() macro. Did C89 mandate that structs had to have a consistent layout? For example, consider the typical layout of the following structure: struct weird { int x; /* sizeof(int)==4 here */
13
380
by: luke | last post by:
hi all, i have another question. I've read the FAQ regarding my former question (sizeof struct and union) and in question 2.14 it talks about offset macro. #define offsetof(type, mem) ((size_t) \ ((char *)&((type *)0)->mem - (char *)(type *)0)) Can anyone explain me how it works. 1)I can't understand what "0" casted to (type *) means
7
4540
by: Fred Zwarts | last post by:
Consider the following definition: typedef struct { int a; int b; } s; Now I have a function void f (int i) { ... }
8
5870
by: Pawel | last post by:
Hallo group members. //p1.cpp #include <stdio.h> #include <linux/stddef.h> struct Person { int m_age; char* m_name; };
11
2435
by: Kavya | last post by:
offsetof(T,m) (size_t)&(((T*)0)->m) Why do we always start from 0 in this macro to access the offset of structure or union. Does standard guarantees that structure and union reside at address 0? If yes, then what if I have two or more structures. How can they reside at same address?.
24
3503
by: Francine.Neary | last post by:
Just out of personal curiosity :) What do people use offsetof() for? I mean, I can understand why you'd want to be able to take the address of a member of a struct, but you can do that with just &(s.a) or similar. Why you'd care about the offset (which surely depends on how the compiler chooses to lay the struct out in memory), I don't really know. And if you did really care, won't offset(s,a) just be &(s.a) - &s ?
5
1902
by: mihirtr | last post by:
Hi, I have following structures and union typedef struct { int a; int b; char *c; }TEST_1;
0
9734
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
9607
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10397
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10410
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
10138
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...
1
7674
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6897
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
5700
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4353
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

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.