473,394 Members | 1,845 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,394 software developers and data experts.

Valid C++?


Is this code below valid C++? I'd like to use this construct but I'm not
sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};

Thanks,
Andrew
Jun 6 '06 #1
60 3782

andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm not
sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};


Yes it is valid. However, I believe it also results in undefined
behavior.

On the other hand, it is a common technique to use especially in C, for
instance:

diff = (&((foo*)0)->x - ((foo*)0))

or something similar.

Most compilers create code that does what you expect here. Since you
are not reading from x or writing to it its just arith operations on a
pointer variable.

Jun 6 '06 #2
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm not
sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};


Though that seems to work, for the sake of clarity, I would do it
differently. At worst, something like this:

char sameSizeAsFooX[ sizeof foo().x ];

Better, IMHO, would be:

struct foo
{
enum { SIZE = 128 };
char x[SIZE];
};

struct bar
{
char sameSizeAsFooX[ foo::SIZE ];
};

Cheers! --M

Jun 6 '06 #3
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #4
Noah Roberts wrote:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};
Yes it is valid. However, I believe it also results in undefined
behavior.


It does not. The dereferencing behind the -> is never evaluated.
[..]


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #5
mlimber wrote:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};
Though that seems to work, for the sake of clarity, I would do it
differently. At worst, something like this:

char sameSizeAsFooX[ sizeof foo().x ];


This requires 'foo' to be default-constructible, which is not always
possible.
Better, IMHO, would be:

struct foo
{
enum { SIZE = 128 };
char x[SIZE];
};

struct bar
{
char sameSizeAsFooX[ foo::SIZE ];
};


I agree. The problem is that editing 'foo' to introduce 'SIZE' is not
always possible. Besides, the trick with (0)-> can be used in templates
whereas you cannot expect every class that has 'x' member for which you
want to create a corresponding 'sameSizeAs..' also contains 'SIZE'...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #6
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];


It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};


On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).

On the other hand, the only harm it can do inside a sizeof is to make
som rather dumb compiler choke on the expression, and it's an old idiom.

On the third & gripping hand, at the technical level, where we don't
care about how a better design might make the need go away, this is
really a job for the Unimplemented Fake Function, the UFF,

foo& foon();

char samesizeAsFoox[ sizeof( foon().x ) ];
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 6 '06 #7

Alf P. Steinbach wrote:
On the third & gripping hand, at the technical level, where we don't
care about how a better design might make the need go away, this is
really a job for the Unimplemented Fake Function, the UFF,

foo& foon();

char samesizeAsFoox[ sizeof( foon().x ) ];


Heh, cute. Never seen that done before.

Does that remove UB?

Jun 6 '06 #8
Alf P. Steinbach wrote:
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};


On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).


According to 3.2/2 the full expression ((foo*)0)->x is not evaluated.
'sizeof' has the same standing as 'typeid' in this matter, AFAICT.
[..a nice trick with UFF redacted..]


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #9
Alf P. Steinbach wrote:
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];


It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};


On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).


Actually, the exception covers not only typeid, but also sizeof:

"An expression is potentially evaluated unless either it is the operand of
the sizeof operator (5.3.3), or it is the operand of the typeid operator
and does not designate an lvalue of polymorphic class type (5.2.8)."

Jun 6 '06 #10
Noah Roberts wrote:
Alf P. Steinbach wrote:
On the third & gripping hand, at the technical level, where we don't
care about how a better design might make the need go away, this is
really a job for the Unimplemented Fake Function, the UFF,

foo& foon();

char samesizeAsFoox[ sizeof( foon().x ) ];


Heh, cute. Never seen that done before.

Does that remove UB?


It cannot remove what does not exist. Further, it creates a violation
of the ODR, if 'sizeof' expression *were* evaluated. If 'sizeof' is not
evaluated (and it isn't, see 3.2/2), then neither is a violation.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #11

Noah Roberts wrote:
Alf P. Steinbach wrote:
On the third & gripping hand, at the technical level, where we don't
care about how a better design might make the need go away, this is
really a job for the Unimplemented Fake Function, the UFF,

foo& foon();

char samesizeAsFoox[ sizeof( foon().x ) ];


Heh, cute. Never seen that done before.


This doesn't work if you're trying to implement an offset function.

Jun 6 '06 #12
andrew queisser schrieb:
Is this code below valid C++? I'd like to use this construct but I'm not
sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};

Thanks,
Andrew


struct foo {
char x[128];
};

union bar {
struct foo dummy;
char * sameSizeAsFoo;
};

maybe that helps

Regards, Daniel
Jun 6 '06 #13
Noah Roberts wrote:
Noah Roberts wrote:
Alf P. Steinbach wrote:
On the third & gripping hand, at the technical level, where we don't
care about how a better design might make the need go away, this is
really a job for the Unimplemented Fake Function, the UFF,

foo& foon();

char samesizeAsFoox[ sizeof( foon().x ) ];


Heh, cute. Never seen that done before.


This doesn't work if you're trying to implement an offset function.


What's "an offset function"?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #14

Victor Bazarov wrote:
Noah Roberts wrote:
Noah Roberts wrote:
Alf P. Steinbach wrote:

On the third & gripping hand, at the technical level, where we don't
care about how a better design might make the need go away, this is
really a job for the Unimplemented Fake Function, the UFF,

foo& foon();

char samesizeAsFoox[ sizeof( foon().x ) ];

Heh, cute. Never seen that done before.


This doesn't work if you're trying to implement an offset function.


What's "an offset function"?


A function that calculates the offset of a member of course.

Jun 6 '06 #15
Noah Roberts wrote:
Victor Bazarov wrote:
Noah Roberts wrote:
Noah Roberts wrote:
Alf P. Steinbach wrote:

> On the third & gripping hand, at the technical level, where we
> don't care about how a better design might make the need go away,
> this is really a job for the Unimplemented Fake Function, the UFF,
>
> foo& foon();
>
> char samesizeAsFoox[ sizeof( foon().x ) ];

Heh, cute. Never seen that done before.

This doesn't work if you're trying to implement an offset function.


What's "an offset function"?


A function that calculates the offset of a member of course.


Ah... OK. What would be the purpose of it? I don't think I ever had
a need in a function like that, and that's why I'm asking. Thanks!

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #16
* Rolf Magnus:
Alf P. Steinbach wrote:
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).

};

On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).


Actually, the exception covers not only typeid, but also sizeof:

"An expression is potentially evaluated unless either it is the operand of
the sizeof operator (5.3.3), or it is the operand of the typeid operator
and does not designate an lvalue of polymorphic class type (5.2.8)."


No, that isn't the exception that applies to typeid.

And no, it doesn't matter whether a dereferencing is potentially
evaluated or not.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 6 '06 #17
On Tue, 06 Jun 2006 12:11:14 -0700, Noah Roberts wrote:
Victor Bazarov wrote:
Noah Roberts wrote:
> Noah Roberts wrote:
>> Alf P. Steinbach wrote:
>>
>>> On the third & gripping hand, at the technical level, where we don't
>>> care about how a better design might make the need go away, this is
>>> really a job for the Unimplemented Fake Function, the UFF,
>>>
>>> foo& foon();
>>>
>>> char samesizeAsFoox[ sizeof( foon().x ) ];
>>
>> Heh, cute. Never seen that done before.
>
> This doesn't work if you're trying to implement an offset function.


What's "an offset function"?


A function that calculates the offset of a member of course.


Like offsetof() ?
Jun 6 '06 #18

Andre Kostur wrote:
On Tue, 06 Jun 2006 12:11:14 -0700, Noah Roberts wrote:

A function that calculates the offset of a member of course.


Like offsetof() ?


yes, exactly like that.

usual definition something like so:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

As to the question of usefulness - not very. Not in C++ anyway.

Jun 6 '06 #19

"Noah Roberts" <ro**********@gmail.com> skrev i meddelandet
news:11**********************@g10g2000cwb.googlegr oups.com...

Andre Kostur wrote:
On Tue, 06 Jun 2006 12:11:14 -0700, Noah Roberts wrote:

> A function that calculates the offset of a member of course.


Like offsetof() ?


yes, exactly like that.

usual definition something like so:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

As to the question of usefulness - not very. Not in C++ anyway.


And that isn't really valid C++ anyway.

It is only *if* the compiler implementor cares to define the behavior
for the offsetof macro, that this works. Otherwise not.

An equally common definition is

#define offsetof(_Structure, _Member)
__builtin_offsetof(_Structure, _Member)

where the compiler people (gcc) have chosen to support another trick.
Bo Persson
Jun 6 '06 #20
Victor Bazarov wrote:
mlimber wrote:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};


Though that seems to work, for the sake of clarity, I would do it
differently. At worst, something like this:

char sameSizeAsFooX[ sizeof foo().x ];


This requires 'foo' to be default-constructible, which is not always
possible.
Better, IMHO, would be:

struct foo
{
enum { SIZE = 128 };
char x[SIZE];
};

struct bar
{
char sameSizeAsFooX[ foo::SIZE ];
};


I agree. The problem is that editing 'foo' to introduce 'SIZE' is not
always possible. Besides, the trick with (0)-> can be used in templates
whereas you cannot expect every class that has 'x' member for which you
want to create a corresponding 'sameSizeAs..' also contains 'SIZE'...


Agreed on all counts. If it is possible, however, it is better to write
more readable (less obscure) code. As Kernighan's Law states:
"Debugging is twice as hard as writing the program, so if you write the
program as cleverly as you can, by definition, you won't be clever
enough to debug it."

Cheers! --M

Jun 6 '06 #21
mlimber wrote:
[..] As Kernighan's Law states:
"Debugging is twice as hard as writing the program, so if you write
the program as cleverly as you can, by definition, you won't be clever
enough to debug it."


Kerhighan cheated here. "Hard" does not necessarily mean "impossible
to comprehend", simply "more effort required". The second part ought
to be ".. so if you strain yourself to the limit writing the program,
by definition, you won't have enough resources to debug it."

I often have to debug programs that aren't really written in a clever
way by any stretch of the meaning. But it's hard nonetheless. Which
brings out another side of the coin: sometimes if one writes a program
as cleverly as one can, it's quite hard for *somebody else* to debug.
Regardless of the relative abilities of those two people, BTW. And yet
another point in the same discussion: often the most difficult programs
to debug are the ones written applying almost no brain whatsoever.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 6 '06 #22
Victor Bazarov wrote:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];


It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};

what's wrong with:

char sameSizeAsFoox[ sizeof (foo::x) ];
(OK, so I'm atavistic, I *like* parens around my sizeof argument).
Jun 6 '06 #23
* red floyd:
struct foo
{
char x[128];
};


what's wrong with:

char sameSizeAsFoox[ sizeof (foo::x) ];

(OK, so I'm atavistic, I *like* parens around my sizeof argument).


It doesn't compile.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 6 '06 #24
Alf P. Steinbach wrote:
* red floyd:
struct foo
{
char x[128];
};


what's wrong with:

char sameSizeAsFoox[ sizeof (foo::x) ];

(OK, so I'm atavistic, I *like* parens around my sizeof argument).


It doesn't compile.

Ok, that's a real good answer to what's wrong with it! :-)
Jun 6 '06 #25
red floyd wrote:
Alf P. Steinbach wrote:
* red floyd:
> struct foo
> {
> char x[128];
> };

what's wrong with:

char sameSizeAsFoox[ sizeof (foo::x) ];

(OK, so I'm atavistic, I *like* parens around my sizeof argument).


It doesn't compile.

Ok, that's a real good answer to what's wrong with it! :-)


Talk about a brain fart!
Jun 6 '06 #26
Alf P. Steinbach wrote:
* Rolf Magnus:

[snip]
Actually, the exception covers not only typeid, but also sizeof:

"An expression is potentially evaluated unless either it is the operand
of the sizeof operator (5.3.3), or it is the operand of the typeid
operator and does not designate an lvalue of polymorphic class type
(5.2.8)."


No, that isn't the exception that applies to typeid.

And no, it doesn't matter whether a dereferencing is potentially
evaluated or not.


That sounds like a defect. Would you please give chapter and verse on this
one.
Best

Kai-Uwe Bux
Jun 7 '06 #27

andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm not
sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};

Thanks,
Andrew


2 other things to note (besides what has been mentioned in other
replies):

1. some compilers will give a warning about the NULL dereference (ie
XCode/gcc). But to fix that you can replace 0 with 32 or whatever.
Similarly for offsetof:

#define myoffsetof(S, m) ((char *)(&(((S) *)32)->m) - 32)

why would you need to make that when there is offsetof() already?
Because the compiler (XCode/gcc again) will complain about using
offsetof for non-POD structures. (But the macro still seems to work as
expected.)

2. if 'x' was an array of doubles instead of an array of chars, you may
(depending on what you want to do with all this) also need to ensure
that your alignment requirements are correct. ie:

struct foo
{
double x[16];
};

struct bar
{
char sameSizeAsFooXButNotSameAlignment[sizeof((foo*)0->x)];
};

struct foo2
{
char achar;
foo afoo;
};

struct bar2
{
char achar;
bar abar;
}

// depending on your alignment settings, this may or may not compile:
typedef int assert[sizeof(foo2) == sizeof(bar2) ? 1 : -1];
take a look at boost type_traits and alignment_of for help with that.

Tony

Jun 7 '06 #28
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
* Rolf Magnus:

[snip]
Actually, the exception covers not only typeid, but also sizeof:

"An expression is potentially evaluated unless either it is the operand
of the sizeof operator (5.3.3), or it is the operand of the typeid
operator and does not designate an lvalue of polymorphic class type
(5.2.8)."

No, that isn't the exception that applies to typeid.

And no, it doesn't matter whether a dereferencing is potentially
evaluated or not.


That sounds like a defect. Would you please give chapter and verse on this
one.


The typeid defect is being addressed, but the proposed resolution is to
allow null-pointer dereferencing in general; see typeid.

The nullpointer dereferencing no matter runtime evaluation or not is
because nullpointer dereferencing is stated (twice) as undefined
behavior without reference to runtime or compile time evaluation.

More about that: the para that Rolf Magnus quoted /defines/ the term
"used" as appearing in a potentially evaluated expression, and restricts
it applicability to objects and functions. The nullpointer constant is
not an object, and so it's formally never "used". It's in the same
league as division by zero: compile time or not doesn't matter.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 7 '06 #29

Alf P. Steinbach wrote:
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];


It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};


On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).

If dereferencing a null pointer means only the use of operator* to
create an lvalue, then, dereferencing a null pointer is not UB.
However, applying a lvalue-to-rvalue conversion to an lvalue or
assigning an lvalue, has UB if the lvalue refers to a an
invalid/inexisting object.
int*p=NULL;
*p=0; // UB
(*p)+0; // UB
*p; // ok
&(*p); // ok

But the standard actually states that lvalue-to-rvalue conversions in
subexpressions of sizeof expressions, are not "accessing" the data, and
I think that the intent was to say that it is not UB.

"
4.1 Lvalue-to-rvalue conversion [conv.lval]
2 The value contained in the object indicated by the lvalue is
the
rvalue result. When an lvalue-to-rvalue conversion occurs within
the
operand of sizeof (_expr.sizeof_) the value contained in the
refer-
enced object is not accessed, since that operator does not
evaluate
its operand.
"
So I think that the standard allows that for sizeof.

Jun 7 '06 #30
* SuperKoko:
Alf P. Steinbach wrote:
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).

};

On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).

If dereferencing a null pointer means only the use of operator* to
create an lvalue, then, dereferencing a null pointer is not UB.


Currently it is, in C++, and isn't, in C99.

It seems that C++0x will be more like C99 in this respect.

So if you'd just waited a few years before posting, you'd have been
right! ;-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 7 '06 #31

<go**********@gmail.com> wrote in message
news:11**********************@y43g2000cwc.googlegr oups.com...

andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm not
sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
};

Thanks,
Andrew


2 other things to note (besides what has been mentioned in other
replies):

1. some compilers will give a warning about the NULL dereference (ie
XCode/gcc). But to fix that you can replace 0 with 32 or whatever.
Similarly for offsetof:

#define myoffsetof(S, m) ((char *)(&(((S) *)32)->m) - 32)

why would you need to make that when there is offsetof() already?
Because the compiler (XCode/gcc again) will complain about using
offsetof for non-POD structures. (But the macro still seems to work as
expected.)

2. if 'x' was an array of doubles instead of an array of chars, you may
(depending on what you want to do with all this) also need to ensure
that your alignment requirements are correct. ie:

struct foo
{
double x[16];
};

struct bar
{
char sameSizeAsFooXButNotSameAlignment[sizeof((foo*)0->x)];
};

struct foo2
{
char achar;
foo afoo;
};

struct bar2
{
char achar;
bar abar;
}

// depending on your alignment settings, this may or may not compile:
typedef int assert[sizeof(foo2) == sizeof(bar2) ? 1 : -1];
take a look at boost type_traits and alignment_of for help with that.

Tony


Yeah, that's exactly the kind of stuff I'm running into - worse I'm also
throwing .NET marshalling in the mix. There are three chunks of code, one in
an embedded system (GCC), one in a C++ DLL (VC++) and one in a .NET app.

Thanks for the tip of using a non-0 constant for the fake pointer.

Andrew
Jun 7 '06 #32
Thanks to everyone for the comments. I don't understand the spec issues
around whether the sizeof expression should ever be evaluated but what I've
heard is good enough for my gut to accept this trick.

I do like the foo::SIZE approach but I'm going to use this in C as well
where foo::SIZE will definitely not work.

Andrew
Jun 7 '06 #33
andrew queisser wrote:
Thanks to everyone for the comments. I don't understand the spec
issues around whether the sizeof expression should ever be evaluated
but what I've heard is good enough for my gut to accept this trick.

I do like the foo::SIZE approach but I'm going to use this in C as
well where foo::SIZE will definitely not work.


It will if you pull it out of the struct. Just define a global const
with that value and name like 'foo_x_SIZE' and use it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 7 '06 #34
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
* Rolf Magnus: [snip]
Actually, the exception covers not only typeid, but also sizeof:

"An expression is potentially evaluated unless either it is the operand
of the sizeof operator (5.3.3), or it is the operand of the typeid
operator and does not designate an lvalue of polymorphic class type
(5.2.8)."
No, that isn't the exception that applies to typeid.

And no, it doesn't matter whether a dereferencing is potentially
evaluated or not.


That sounds like a defect. Would you please give chapter and verse on
this one.


The typeid defect is being addressed, but the proposed resolution is to
allow null-pointer dereferencing in general; see typeid.


Do you know the number of the defect report?
The nullpointer dereferencing no matter runtime evaluation or not is
because nullpointer dereferencing is stated (twice) as undefined
behavior without reference to runtime or compile time evaluation.
Could you point me two those two clauses in the standard.
More about that: the para that Rolf Magnus quoted /defines/ the term
"used" as appearing in a potentially evaluated expression, and restricts
it applicability to objects and functions. The nullpointer constant is
not an object, and so it's formally never "used". It's in the same
league as division by zero: compile time or not doesn't matter.


Thanks for the explanation.
Best

Kai-Uwe Bux
Jun 7 '06 #35
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Alf P. Steinbach wrote:

* Rolf Magnus:
[snip]
> Actually, the exception covers not only typeid, but also sizeof:
>
> "An expression is potentially evaluated unless either it is the operand
> of the sizeof operator (5.3.3), or it is the operand of the typeid
> operator and does not designate an lvalue of polymorphic class type
> (5.2.8)."
No, that isn't the exception that applies to typeid.

And no, it doesn't matter whether a dereferencing is potentially
evaluated or not.
That sounds like a defect. Would you please give chapter and verse on
this one.

The typeid defect is being addressed, but the proposed resolution is to
allow null-pointer dereferencing in general; see typeid.


Do you know the number of the defect report?


No, sorry, I don't recall, execpt that it isn't about typeid per se;
it's about nullpointer dereferencing and one-past-array access.

Hey, wait a minute, I had some correspondence about that.

[searching inbox...]

OK, "CWG 232", that's from correspondence related to a comp.std.c++
thread titled "Are references to not-quite-objects legal?", late 2005.

Probably that's the one; it's at <url:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#232>.

It's a bit funny because it starts out noting the current wording of the
standard (UB), then goes on to discuss original intent, and concludes
that all's OK because of the intent -- which it definitely isn't,
since otherwise that DR wouldn't have existed.

The nullpointer dereferencing no matter runtime evaluation or not is
because nullpointer dereferencing is stated (twice) as undefined
behavior without reference to runtime or compile time evaluation.


Could you point me to those two clauses in the standard.


The first one is the definition of "undefined behavior". :-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 7 '06 #36
red floyd wrote:
struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];


It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};

what's wrong with:

char sameSizeAsFoox[ sizeof (foo::x) ];


A simple solution:

struct foo {
typedef char TypeOfX [128];
TypeOfX x;
};

struct bar {
char sameSizeAsFooX[ sizeof (foo::TypeOfX) ];
};
--
Salu2

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
Jun 7 '06 #37
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Alf P. Steinbach wrote:

> * Rolf Magnus:
[snip]
>> Actually, the exception covers not only typeid, but also sizeof:
>>
>> "An expression is potentially evaluated unless either it is the
>> operand of the sizeof operator (5.3.3), or it is the operand of the
>> typeid operator and does not designate an lvalue of polymorphic class
>> type (5.2.8)."
> No, that isn't the exception that applies to typeid.
>
> And no, it doesn't matter whether a dereferencing is potentially
> evaluated or not.
That sounds like a defect. Would you please give chapter and verse on
this one.
The typeid defect is being addressed, but the proposed resolution is to
allow null-pointer dereferencing in general; see typeid.


Do you know the number of the defect report?


No, sorry, I don't recall, execpt that it isn't about typeid per se;
it's about nullpointer dereferencing and one-past-array access.

Hey, wait a minute, I had some correspondence about that.

[searching inbox...]

OK, "CWG 232", that's from correspondence related to a comp.std.c++
thread titled "Are references to not-quite-objects legal?", late 2005.

Probably that's the one; it's at <url:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#232>.

It's a bit funny because it starts out noting the current wording of the
standard (UB), then goes on to discuss original intent, and concludes
that all's OK because of the intent -- which it definitely isn't,
since otherwise that DR wouldn't have existed.

The nullpointer dereferencing no matter runtime evaluation or not is
because nullpointer dereferencing is stated (twice) as undefined
behavior without reference to runtime or compile time evaluation.


Could you point me to those two clauses in the standard.


The first one is the definition of "undefined behavior". :-)


Should you be referring to 1.3.12, I would like to ask how you arrive at the
conclusion that sizeof( ((foo*)0)->x ) is undefined from the wording of
1.3.12. Your original claim was:

On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).

I have tried to derive this claim for the wording in the standard, but I
failed. Could you please provide a reasoning that is a little more detailed
an open to verification.
Best

Kai-Uwe Bux

Jun 7 '06 #38
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Alf P. Steinbach wrote:

* Kai-Uwe Bux:
> Alf P. Steinbach wrote:
>
>> * Rolf Magnus:
> [snip]
>>> Actually, the exception covers not only typeid, but also sizeof:
>>>
>>> "An expression is potentially evaluated unless either it is the
>>> operand of the sizeof operator (5.3.3), or it is the operand of the
>>> typeid operator and does not designate an lvalue of polymorphic class
>>> type (5.2.8)."
>> No, that isn't the exception that applies to typeid.
>>
>> And no, it doesn't matter whether a dereferencing is potentially
>> evaluated or not.
> That sounds like a defect. Would you please give chapter and verse on
> this one.
The typeid defect is being addressed, but the proposed resolution is to
allow null-pointer dereferencing in general; see typeid.
Do you know the number of the defect report?

No, sorry, I don't recall, execpt that it isn't about typeid per se;
it's about nullpointer dereferencing and one-past-array access.

Hey, wait a minute, I had some correspondence about that.

[searching inbox...]

OK, "CWG 232", that's from correspondence related to a comp.std.c++
thread titled "Are references to not-quite-objects legal?", late 2005.

Probably that's the one; it's at <url:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#232>.

It's a bit funny because it starts out noting the current wording of the
standard (UB), then goes on to discuss original intent, and concludes
that all's OK because of the intent -- which it definitely isn't,
since otherwise that DR wouldn't have existed.

The nullpointer dereferencing no matter runtime evaluation or not is
because nullpointer dereferencing is stated (twice) as undefined
behavior without reference to runtime or compile time evaluation.
Could you point me to those two clauses in the standard.

The first one is the definition of "undefined behavior". :-)


Should you be referring to 1.3.12, I would like to ask how you arrive at the
conclusion that sizeof( ((foo*)0)->x ) is undefined from the wording of
1.3.12. Your original claim was:

On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).

I have tried to derive this claim for the wording in the standard, but I
failed. Could you please provide a reasoning that is a little more detailed
an open to verification.


Sorry about the vague description, I thought you'd find it readily
enough, especially since mentioned in the DR I linked to: it's §1.9/4.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 7 '06 #39
On Tue, 06 Jun 2006 20:09:41 +0200, "Alf P. Steinbach"
<al***@start.no> wrote in comp.lang.c++:
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).
};


On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).


Yes, dereferencing a null pointer is undefined behavior. However
since the C++ standard (like the C standard) states:

"The sizeof operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is not evaluated, or a parenthesized typeid."

Since the expression is itself is not evaluated, the pointer is never
dereferenced, and the behavior is completely defined.
On the other hand, the only harm it can do inside a sizeof is to make
som rather dumb compiler choke on the expression, and it's an old idiom.

On the third & gripping hand, at the technical level, where we don't
care about how a better design might make the need go away, this is
really a job for the Unimplemented Fake Function, the UFF,

foo& foon();

char samesizeAsFoox[ sizeof( foon().x ) ];


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
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
Jun 8 '06 #40
On Tue, 06 Jun 2006 21:41:07 +0200, "Alf P. Steinbach"
<al***@start.no> wrote in comp.lang.c++:
* Rolf Magnus:
Alf P. Steinbach wrote:
* Victor Bazarov:
andrew queisser wrote:
> Is this code below valid C++? I'd like to use this construct but I'm
> not sure if it'll be portable.
>
> struct foo
> {
> char x[128];
> };
> struct bar
> {
> char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).

> };
On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).


Actually, the exception covers not only typeid, but also sizeof:

"An expression is potentially evaluated unless either it is the operand of
the sizeof operator (5.3.3), or it is the operand of the typeid operator
and does not designate an lvalue of polymorphic class type (5.2.8)."


No, that isn't the exception that applies to typeid.

And no, it doesn't matter whether a dereferencing is potentially
evaluated or not.


The statement above makes no sense. I have no idea what "potentially
evaluated" means.

Consider:

int main()
{
int x = 0;
int *ip = 0;
if (x)
{
x = *ip;
}
return x;
}

This program has completely defined behavior, and in fact main() will
return 0. The program contains an expression that would cause UB,
namely dereferencing a null pointer. But dereferencing a null (or
otherwise invalid) pointer can only cause UB if it is actually
executed at run time. That cannot happen in the sample as written,
because the expression is never evaluated.

The standard guarantees that if the operand of sizeof operator is an
expression, that expression is not evaluated. The expression is only
parsed, at compile time, to determine the type of the expression.
Since it may only be applied to complete types, the compiler knows the
size of the object representation from the type. The pointer is not
dereferenced, and in fact does not actually exist at compile time.

All of these are perfectly legal and defined:

sizeof 1/0; // yields sizeof(int)
sizeof 100.0/0 // yields sizeof(double)

....and given:

struct z { int x; double y );
struct z *zp = 0;

....then:

sizeof zp->y; // yields sizeof(double)

....is likewise perfectly legal, and so is:

sizeof (z*)0->y;

The actual temporary pointer is never formed, let along dereferenced.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
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
Jun 8 '06 #41
* Jack Klein:
On Tue, 06 Jun 2006 21:41:07 +0200, "Alf P. Steinbach"
<al***@start.no> wrote in comp.lang.c++:
* Rolf Magnus:
Alf P. Steinbach wrote:

* Victor Bazarov:
> andrew queisser wrote:
>> Is this code below valid C++? I'd like to use this construct but I'm
>> not sure if it'll be portable.
>>
>> struct foo
>> {
>> char x[128];
>> };
>> struct bar
>> {
>> char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
> It is OK, I guess. Seems rather dangerous though, like dereferencing
> a null pointer. Perhaps it would be less scary to do
>
> char sameSizeAsFoox[ sizeof foo().x ];
>
> (although it does require for 'foo' to be default-constructible while
> your solution does not).
>
>> };
On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).
Actually, the exception covers not only typeid, but also sizeof:

"An expression is potentially evaluated unless either it is the operand of
the sizeof operator (5.3.3), or it is the operand of the typeid operator
and does not designate an lvalue of polymorphic class type (5.2.8)." No, that isn't the exception that applies to typeid.

And no, it doesn't matter whether a dereferencing is potentially
evaluated or not.


The statement above makes no sense. I have no idea what "potentially
evaluated" means.


It's a term defined by the standard; the definition is quoted above the
sentence using that term.

"potentially evaluated" is in turn used to defined the term "used".

Which is limited to objects and functions.

Consider:

int main()
{
int x = 0;
int *ip = 0;
if (x)
{
x = *ip;
}
return x;
}

This program has completely defined behavior,
Yes.
[snip] All of these are perfectly legal and defined:

sizeof 1/0; // yields sizeof(int)


Nope.

The standard says that if the second operand is zero, the result is
undefined behavior.

It doesn't distinguish sizeof expressions as exempt from that, and in
fact at least one very popular compiler, VC 7.1, chokes on the above.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 8 '06 #42
* Jack Klein:
On Tue, 06 Jun 2006 20:09:41 +0200, "Alf P. Steinbach"
<al***@start.no> wrote in comp.lang.c++:
* Victor Bazarov:
andrew queisser wrote:
Is this code below valid C++? I'd like to use this construct but I'm
not sure if it'll be portable.

struct foo
{
char x[128];
};
struct bar
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).

};

On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).


Yes, dereferencing a null pointer is undefined behavior. However
since the C++ standard (like the C standard) states:

"The sizeof operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is not evaluated, or a parenthesized typeid."

Since the expression is itself is not evaluated, the pointer is never
dereferenced, and the behavior is completely defined.


Nope.

Dereferenced doesn't mean "at run time".

Since it's UB the compiler can assign any meaning to it, including that
*p, when p == 0 is known at compile time, yields a 'double'.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 8 '06 #43
Alf P. Steinbach wrote:
* Jack Klein:
All of these are perfectly legal and defined:

sizeof 1/0; // yields sizeof(int)


Nope.

The standard says that if the second operand is zero, the result is
undefined behavior.

It doesn't distinguish sizeof expressions as exempt from that, and in
fact at least one very popular compiler, VC 7.1, chokes on the above.


I think he meant:
sizeof (1/0);

Jun 8 '06 #44
Alf P. Steinbach wrote:
* Jack Klein:
On Tue, 06 Jun 2006 20:09:41 +0200, "Alf P. Steinbach"
<al***@start.no> wrote in comp.lang.c++:
* Victor Bazarov:
andrew queisser wrote:
> Is this code below valid C++? I'd like to use this construct but I'm
> not sure if it'll be portable.
>
> struct foo
> {
> char x[128];
> };
> struct bar
> {
> char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
It is OK, I guess. Seems rather dangerous though, like dereferencing
a null pointer. Perhaps it would be less scary to do

char sameSizeAsFoox[ sizeof foo().x ];

(although it does require for 'foo' to be default-constructible while
your solution does not).

> };
On the one hand, dereferencing a null-pointer is formally UB no matter
which context (except in a typeid expression).
Yes, dereferencing a null pointer is undefined behavior. However
since the C++ standard (like the C standard) states:

"The sizeof operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is not evaluated, or a parenthesized typeid."

Since the expression is itself is not evaluated, the pointer is never
dereferenced, and the behavior is completely defined.


Nope.

Dereferenced doesn't mean "at run time".


Ok, but how do you argue that a dereferencing takes place at compile time?
The standard says the expression is not evaluated, it does not say the
expression is evaluated at compile time.

Since it's UB the compiler can assign any meaning to it, including that
*p, when p == 0 is known at compile time, yields a 'double'.

Best

Kai-Uwe Bux
Jun 8 '06 #45
* Kai-Uwe Bux:

Ok, but how do you argue that a dereferencing takes place at compile time?
The standard says the [sizeof] expression is not evaluated, it does not say the
expression is evaluated at compile time.


Consider

template< int x > struct S{ char c[x]; };

int main()
{
int y = sizeof( S<5/0> );
}

Can we allow for a teeny tiny little bit of evaluation, do you think?

Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 8 '06 #46
Kai-Uwe Bux wrote:
Alf P. Steinbach wrote:
* Jack Klein:
Since the expression is itself is not evaluated, the pointer is
never dereferenced, and the behavior is completely defined.


Nope.

Dereferenced doesn't mean "at run time".


Ok, but how do you argue that a dereferencing takes place at compile
time? The standard says the expression is not evaluated, it does not
say the expression is evaluated at compile time.


I think we need to account free-standing implementations and some C++
interpreters along with them. Undefined behaviour cannot be split
into "compile-time" and "run-time" for those, can it? Is there
anything in the Standard that prohibits an interpreting implementation?
An interpreter will dereference everything at compile time.

"Undefined behaviour" defined without splitting it into "undefined
behaviour for the compiler" and "undefined behaviour for the compiled
code", AFAICT. We may want it to be, there is an illusion that it is,
but it isn't. Or is it?
Since it's UB the compiler can assign any meaning to it, including
that *p, when p == 0 is known at compile time, yields a 'double'.


Or the compiler may format your hard drive instead...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 8 '06 #47
Alf P. Steinbach wrote:
* Kai-Uwe Bux:

Ok, but how do you argue that a dereferencing takes place at compile
time? The standard says the [sizeof] expression is not evaluated, it does
not say the expression is evaluated at compile time.


Consider

template< int x > struct S{ char c[x]; };

int main()
{
int y = sizeof( S<5/0> );
}

Can we allow for a teeny tiny little bit of evaluation, do you think?


'S<5/0>' is not an expression that is "not evaluated". It's a type-id.
5.3.3/1 clearly delineates the two.

There *is* a difference between const expressions which *need* to be
evaluated (especially during instantiating of a template) and const
expressions sitting directly in the sizeof.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 8 '06 #48
* Victor Bazarov:
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Ok, but how do you argue that a dereferencing takes place at compile
time? The standard says the [sizeof] expression is not evaluated, it does
not say the expression is evaluated at compile time. Consider

template< int x > struct S{ char c[x]; };

int main()
{
int y = sizeof( S<5/0> );
}

Can we allow for a teeny tiny little bit of evaluation, do you think?


'S<5/0>' is not an expression that is "not evaluated". It's a type-id.
5.3.3/1 clearly delineates the two.


Nope, 5/0 is an expression.

Anyway, you can make the whole sizeof argument a value producing
expression if you want.

So that distinction is irrelevant: it's been demonstrated that there is
evaluation.

There *is* a difference between const expressions which *need* to be
evaluated (especially during instantiating of a template) and const
expressions sitting directly in the sizeof.


Yes, I agree, but not with regard to the formal rules: it's a QOI issue.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 8 '06 #49
Victor Bazarov wrote:
Kai-Uwe Bux wrote:
Alf P. Steinbach wrote:
* Jack Klein:
Since the expression is itself is not evaluated, the pointer is
never dereferenced, and the behavior is completely defined.

Nope.

Dereferenced doesn't mean "at run time".
Ok, but how do you argue that a dereferencing takes place at compile
time? The standard says the expression is not evaluated, it does not
say the expression is evaluated at compile time.


I think we need to account free-standing implementations and some C++
interpreters along with them. Undefined behaviour cannot be split
into "compile-time" and "run-time" for those, can it? Is there
anything in the Standard that prohibits an interpreting implementation?
An interpreter will dereference everything at compile time.


The standard says the expression is not evaluated. An interpreter is not
supposed to evaluate it either. So why/when would dereferencing occur?

"Undefined behaviour" defined without splitting it into "undefined
behaviour for the compiler" and "undefined behaviour for the compiled
code", AFAICT. We may want it to be, there is an illusion that it is,
but it isn't. Or is it?


Your arguing a point never disputed. What is under dispute is whether

sizeof( ((foo*)0)->x )

involves dereferencing. Alf seems to read the phrase "the expression is not
evaluated" to mean "possibly evaluated at compile time". That is what
triggered my question.
Since it's UB the compiler can assign any meaning to it, including
that *p, when p == 0 is known at compile time, yields a 'double'.


Or the compiler may format your hard drive instead...


Only if it actually is UB, which is under dispute.
Best

Kai-Uwe Bux

Jun 8 '06 #50

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

Similar topics

12
by: lawrence | last post by:
I have a string which I want to send to eval(). How can I test it ahead of time to make sure it is valid code? I don't want to send it to eval and get parse errors. I want to do something like...
16
by: siliconmike | last post by:
Hi, I'm looking for a reliable script that would connect to a host and somehow determine whether an email address is valid. since getmxrr() only gets the mx records.. Links/pointers ? Mike
1
by: Anna | last post by:
Hi all. I have probably a rather stupid question. If there is an HTML document, XML-formed using JTidy, is there any tool to convert it to valid XHTML? I.e. so that all the tags and attribute...
7
by: JR | last post by:
Hey all, I have read part seven of the FAQ and searched for an answer but can not seem to find one. I am trying to do the all too common verify the data type with CIN. The code from the FAQ...
23
by: James Aguilar | last post by:
Someone showed me something today that I didn't understand. This doesn't seem like it should be valid C++. Specifically, I don't understand how the commas are accepted after the function...
3
by: Chris | last post by:
Hi, In C# I tried to save a file from a generated file name. Just before launching the dialog I check for a valid file name to be sure. There for I used the method ValidateNames from the save...
0
by: QA | last post by:
I am using a Business Scorecard Accelarator in a Sharepoint Portal 2003 using SQL Server 2005 I am getting the following error: Error,5/7/2005 10:50:14 AM,580,AUE1\Administrator,"Specified cast is...
1
by: Robert Morgan | last post by:
|I'm trying to run a query on a database using php and postgres functions ||<?php db_connect(); $stat = pg_exec($connstr,"SELECT WSID from tblWorkstation "); while ($row = pg_fetch_rows($stat))...
1
by: illegal.prime | last post by:
Hey all, I have an app, that could take two numbers of any type of numerical type int, long, double, float, uint, ulong, etc. I want to check that the numbers are part of a range that I consider...
10
by: SpreadTooThin | last post by:
Hi I'm writing a python script that creates directories from user input. Sometimes the user inputs characters that aren't valid characters for a file or directory name. Here are the characters...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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...
0
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,...
0
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...
0
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...

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.