473,320 Members | 2,073 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Why won't the compiler tell??

Consider this:

typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??

The only way this works is if I have declared a variable of type foo...yet
the compiler knows quite well what the answer to what I am asking.

This just seems like something the compilers should be able to handle.

-Mark
Jul 22 '05 #1
19 1274
"Mark Rance" <mr*@pcisys.network> wrote
Consider this:

typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??

The only way this works is if I have declared a variable of type foo...yet
the compiler knows quite well what the answer to what I am asking.

This just seems like something the compilers should be able to handle.


sizeof gives you the size of a type (or the size of the type of the result of
an expression). 'foo.b' is neither, nor is it a valid syntactic construct. One
way to get the size is to do sizeof(((foo *)0)->b). There's no danger because
the expression never gets evaluated and so you're not actually dereferencing a
zero pointer. Only the type of the result is determined.

Claudio Puviani
Jul 22 '05 #2
Claudio Puviani wrote:
[snip]
sizeof gives you the size of a type (or the size of the type of the result of
an expression). 'foo.b' is neither, nor is it a valid syntactic construct. One
way to get the size is to do sizeof(((foo *)0)->b). There's no danger because
the expression never gets evaluated and so you're not actually dereferencing a
zero pointer. Only the type of the result is determined.


As an aside, did you see how much crap I got from posting my compiler's
implementation of the offsetof macro that is based on similar non-evaluated
dereferencing? I was trying to point out that there are legitimate uses for
macros, and instead several found course to attack me because that
implementation leads to undefined behavior in their mind.
Jul 22 '05 #3
"Julie" <ju***@nospam.com> wrote
Claudio Puviani wrote:
[snip]
sizeof gives you the size of a type (or the size of the type of the result of an expression). 'foo.b' is neither, nor is it a valid syntactic construct. One way to get the size is to do sizeof(((foo *)0)->b). There's no danger because the expression never gets evaluated and so you're not actually dereferencing a zero pointer. Only the type of the result is determined.


As an aside, did you see how much crap I got from posting my compiler's
implementation of the offsetof macro that is based on similar non-evaluated
dereferencing? I was trying to point out that there are legitimate uses for
macros, and instead several found course to attack me because that
implementation leads to undefined behavior in their mind.


No, I missed that. It's a surprising reaction, since most C++ programmers have
a similar macro (usually implementing OFFSET_OF) somewhere in their toolbox.

Claudio Puviani
Jul 22 '05 #4
"Mark Rance" <mr*@pcisys.network> wrote in message
typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??


Does sizeof(foo::b) work?

Jul 22 '05 #5
Claudio Puviani wrote:
"Julie" <ju***@nospam.com> wrote
Claudio Puviani wrote:
[snip]
sizeof gives you the size of a type (or the size of the type of the result
of
an expression). 'foo.b' is neither, nor is it a valid syntactic construct.
One
way to get the size is to do sizeof(((foo *)0)->b). There's no danger
because
the expression never gets evaluated and so you're not actually
dereferencing a
zero pointer. Only the type of the result is determined.

If you're not willing to get something better than Outlook Express to
avoid this mangling of posts, please fix the mutilated text by hand.
As an aside, did you see how much crap I got from posting my compiler's
implementation of the offsetof macro that is based on similar non-evaluated
dereferencing? I was trying to point out that there are legitimate uses for
macros,

Precious few.
and instead several found course to attack me because that
implementation leads to undefined behavior in their mind.

No, I missed that. It's a surprising reaction, since most C++ programmers have
a similar macro (usually implementing OFFSET_OF) somewhere in their toolbox.


Don't have one, never needed one.
Jul 22 '05 #6
Mark Rance wrote:
Consider this:

typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??

The only way this works is if I have declared a variable of type foo...yet
the compiler knows quite well what the answer to what I am asking.

This just seems like something the compilers should be able to handle.


size_t x = sizeof foo ().b;

--
Regards,
Buster.
Jul 22 '05 #7
"Jeff Schwab" <je******@comcast.net> wrote
If you're not willing to get something better than Outlook Express to
avoid this mangling of posts, please fix the mutilated text by hand.


The text gets mutilated when I hit send, not while I have a chance to edit it.
Every once in a while, if I reply to someone who wraps their text at 1
character more than my setting, weird line breaks can happen. I won't change my
newsreader or feel guilty if once every few weeks, one message turns out to be
unaesthetic.

Claudio Puviani
Jul 22 '05 #8
"Buster" <no***@nowhere.com> wrote
Mark Rance wrote:
Consider this:

typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??

The only way this works is if I have declared a variable of type
foo...yet the compiler knows quite well what the answer to what
I am asking.

This just seems like something the compilers should be able to handle.


size_t x = sizeof foo ().b;


That's not a generic solution. It only works for types that have a visible
default constructor. Some types don't have ANY visible constructors.

Claudio Puviani
Jul 22 '05 #9
"Siemel Naran" <Si*********@REMOVE.att.net> wrote
"Mark Rance" <mr*@pcisys.network> wrote in message
typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??


Does sizeof(foo::b) work?


Think about it: is there a 'b' in the context/scope of 'foo'? Of course not. 'b'
exists in the context of an INSTANCE of 'foo', not in the context of the class
itself. If 'b' were a class static, then you could do sizeof(foo::b) because 'b'
would the exist in the context of class 'foo'.

Claudio Puviani
Jul 22 '05 #10
Claudio Puviani wrote:
"Siemel Naran" <Si*********@REMOVE.att.net> wrote
"Mark Rance" <mr*@pcisys.network> wrote in message
> typedef struct
> {
> char a[10];
> char b[5];
> char c[3];
> } foo;
>
> Why can I not execute a statement like:
>
> size_t x = sizeof(foo.b); ??
Does sizeof(foo::b) work?


Think about it: is there a 'b' in the context/scope of 'foo'?


Yes.
Of course not. 'b' exists in the context of an INSTANCE of 'foo', not
in the context of the class itself.


char (foo::* p)[5] = &foo::b;

Jul 22 '05 #11
"Rolf Magnus" <ra******@t-online.de> wrote
Claudio Puviani wrote:
"Siemel Naran" <Si*********@REMOVE.att.net> wrote
"Mark Rance" <mr*@pcisys.network> wrote in message

> typedef struct
> {
> char a[10];
> char b[5];
> char c[3];
> } foo;
>
> Why can I not execute a statement like:
>
> size_t x = sizeof(foo.b); ??

Does sizeof(foo::b) work?


Think about it: is there a 'b' in the context/scope of 'foo'?


Yes.
Of course not. 'b' exists in the context of an INSTANCE of 'foo', not
in the context of the class itself.


char (foo::* p)[5] = &foo::b;


You're neglecting the fact that despite the misleading syntax, a
pointer-to-member is only valid in the context of the instance, not of the class.
Except in the declaration of a pointer-to-member -- where the choice of the
syntax was made for the convenience of reusing a token, not for consistency --
foo::b simply does not exist. In the case of a pointer-to-member, foo::b doesn't
refer to the variable b -- evidently, since no such variable exists without an
instance -- but rather is a notational shortcut to represent the concept of an
offset within an eventual instance. Stroustrup describes in detail why he chose
to "cheat", as he puts it, and make the offset LOOK like a pointer (when in fact
it isn't) in 13.11 of "The Design and Evolution of C++".

Claudio Puviani
Jul 22 '05 #12
"Claudio Puviani" <pu*****@hotmail.com> wrote in message news:DlKjc.24409
"Siemel Naran" <Si*********@REMOVE.att.net> wrote
"Mark Rance" <mr*@pcisys.network> wrote in message
typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??
Does sizeof(foo::b) work?


Think about it: is there a 'b' in the context/scope of 'foo'? Of course

not. 'b' exists in the context of an INSTANCE of 'foo', not in the context of the class itself. If 'b' were a class static, then you could do sizeof(foo::b) because 'b' would the exist in the context of class 'foo'.


OK, I tried it on Borland 6, and it gives a compile error (but it could be
an error in the compiler). But still it seems it should work. I believe
that 'b' does exist in the instance of a foo. As foo is a class type, we're
talking of foo::b as a class type too.

Here is a version that compiles and works. But it seems a workaround of the
above concept, so I think it's a defect in the language that the idea is not
supported.
#if defined(__BORLANDC__)
#include <vcl.h>
#endif

#include <iostream>

typedef struct
{
char a[10];
char b[5];
char c[3];
double x;
} foo;

template <class Class, class T, size_t N>
size_t sizeof_member(T (Class::* member)[N])
{
return N*sizeof(T);
}

template <class Class, class T>
size_t sizeof_member(T Class::* member)
{
return sizeof(T);
}

int main(int argc, char * * argv)
{
std::cout << sizeof_member(&foo::b) << '\n'; // prints 5
std::cout << sizeof_member(&foo::x) << '\n'; // prints 8 (could be
different on different platforms)
}
Jul 22 '05 #13
Jeff Schwab <je******@comcast.net> wrote in message news:<R7********************@comcast.com>...
[snip]
If you're not willing to get something better than Outlook Express to
avoid this mangling of posts, please fix the mutilated text by hand.


Curious. The post you were responding to is on google with perfectly
fine line breaks, near as I can see. Don't suppose it's your newsreader
that caused the problems, do you? Nah, you're perfect.
Socks
Jul 22 '05 #14
"Siemel Naran" <Si*********@REMOVE.att.net> wrote in
news:TQ*********************@bgtnsc04-news.ops.worldnet.att.net:
#include <iostream>

typedef struct
{
char a[10];
char b[5];
char c[3];
double x;
} foo; [...] template <class Class, class T>
size_t sizeof_member(T Class::* member)
{
return sizeof(T);
}


or even:

template <typename class_t, typename member_t>
member_t & member_type(member_t class_t::*);

int main(void)
{
std::cout << sizeof(member_type(&foo::b)) << '\n';
std::cout << sizeof(member_type(&foo::x)) << '\n';
}

Though I guess that doesn't really make much difference.

-josh
Jul 22 '05 #15
pu*********@hotmail.com wrote:
Jeff Schwab <je******@comcast.net> wrote in message news:<R7********************@comcast.com>...
[snip]
If you're not willing to get something better than Outlook Express to
avoid this mangling of posts, please fix the mutilated text by hand.

Curious. The post you were responding to is on google with perfectly
fine line breaks, near as I can see. Don't suppose it's your newsreader
that caused the problems, do you?


No.
Nah, you're perfect.


Why would access to a decent news reader make me "perfect?" I didn't
write my news client, and I claim no credit for it.
Jul 22 '05 #16
On Tue, 27 Apr 2004 21:13:06 -0700, Julie <ju***@nospam.com> wrote in
comp.lang.c++:
Claudio Puviani wrote:
[snip]
sizeof gives you the size of a type (or the size of the type of the result of
an expression). 'foo.b' is neither, nor is it a valid syntactic construct. One
way to get the size is to do sizeof(((foo *)0)->b). There's no danger because
the expression never gets evaluated and so you're not actually dereferencing a
zero pointer. Only the type of the result is determined.


As an aside, did you see how much crap I got from posting my compiler's
implementation of the offsetof macro that is based on similar non-evaluated
dereferencing? I was trying to point out that there are legitimate uses for
macros, and instead several found course to attack me because that
implementation leads to undefined behavior in their mind.


There actually is a reason why one is legal and the other is not. The
sizeof operator is *required* by the standard not to evaluate its
operand. There is no such requirement on any other expression that
*appears* to dereference a null pointer. An apparent dereference is
an actual dereference as far as the standard is concerned, which
defines the operation of an abstract machine.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #17
"josh" <sm*************************@yahoo.com.NOSPAM> wrote in message
"Siemel Naran" <Si*********@REMOVE.att.net> wrote in
template <class Class, class T>
size_t sizeof_member(T Class::* member)
{
return sizeof(T);
}


There was another overload.
or even:

template <typename class_t, typename member_t>
member_t & member_type(member_t class_t::*);


Your way is better as it is gives a compile time integral constant that you
can use for the size of an array (though declaring an explicit size is
usually clearer). It is also shorter (just one overload, and no need to
define the function).
Jul 22 '05 #18
no
"Siemel Naran" <Si*********@REMOVE.att.net> wrote in message
news:wN*********************@bgtnsc04-news.ops.worldnet.att.net...
"Mark Rance" <mr*@pcisys.network> wrote in message
typedef struct
{
char a[10];
char b[5];
char c[3];
} foo;

Why can I not execute a statement like:

size_t x = sizeof(foo.b); ??


Does sizeof(foo::b) work?

Jul 22 '05 #19
Jeff Schwab wrote:

Claudio Puviani wrote:
"Julie" <ju***@nospam.com> wrote
Claudio Puviani wrote:
[snip]

sizeof gives you the size of a type (or the size of the type of the result


of
an expression). 'foo.b' is neither, nor is it a valid syntactic construct.


One
way to get the size is to do sizeof(((foo *)0)->b). There's no danger


because
the expression never gets evaluated and so you're not actually


dereferencing a
zero pointer. Only the type of the result is determined.


If you're not willing to get something better than Outlook Express to
avoid this mangling of posts, please fix the mutilated text by hand.


Julie's post didn't mangle AT ALL in my newsreader. (Netscape)
Neither did Claudio's post.

It must be your newsreader that hosed it up.

Mike
Jul 22 '05 #20

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

Similar topics

13
by: Bryan Parkoff | last post by:
You may notice that switch (...) is much faster than function that can gain a big improved performance because it only use JMP instruction however function is required to use CALL, PUSH, and POP...
3
by: Dave C | last post by:
I've written the following code that won't compile, trimmed down to just the pertinent stuff: --- WindowClass.hxx ---------------------------------------------------- #include <set> class...
15
by: Gregg Woodcock | last post by:
My compiler (m68k-gcc) does not allow this (simplified example; not my real code) and I don't see why not: { char *arrayCharPtr1 = {"a", "ab", NULL}; char *arrayCharPtr2 = {"A", "AB", NULL};...
6
by: Adam Warner | last post by:
Hi all, When adding variable length arrays to my program I created the elements as type struct o *. This is because /most/ of the time the VLAs contains pointers to struct o objects (these...
102
by: Skybuck Flying | last post by:
Sometime ago on the comp.lang.c, I saw a teacher's post asking why C compilers produce so many error messages as soon as a closing bracket is missing. The response was simply because the compiler...
16
by: pj | last post by:
(Was originally, probably wrongly, posted to the vc subgroup.) (This doesn't appear to be a c# problem, but a problem with a bug in the Visual Studio c# compiler, but, any help will be welcome...)...
30
by: MikeC | last post by:
Good People, I'm writing a backup utility that uses a chdir() to go into the source directory (in which the files reside that I want to back up), so I don't want to use chdir() to get into the...
3
by: fade | last post by:
Good afternoon Is there a way to tell the compiler and linker where to look for my header files and libraries directly on the code? (I'm not talking about changing project properties, linker,...
1
by: DerekBaker | last post by:
I had this code previously: void App::FillFontBox(HWND PrefsBox) { EnumFontFamilies(hdc,(LPCTSTR)NULL,(FONTENUMPROC)EnumFontNamesProc,(long)this);
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.