Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Valid C++?

Reply
Thread Tools

Valid C++?

 
 
andrew queisser
Guest
Posts: n/a
 
      06-06-2006

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


 
Reply With Quote
 
 
 
 
Noah Roberts
Guest
Posts: n/a
 
      06-06-2006

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.

 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      06-06-2006
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

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-06-2006
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


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-06-2006
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


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-06-2006
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


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      06-06-2006
* 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?
 
Reply With Quote
 
Noah Roberts
Guest
Posts: n/a
 
      06-06-2006

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?

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-06-2006
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


 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      06-06-2006
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.."

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Not valid SSID name during setup using the wizard =?Utf-8?B?SE1WYWNhbmE=?= Wireless Networking 4 08-23-2005 05:38 PM
Enigmail - no valid OpenPGP data found Chuck Firefox 3 04-27-2005 09:20 PM
Enigmail - no valid OpenPGP data found Chuck Firefox 0 04-26-2005 06:41 PM
User Control - InvalidCastException: Specified cast is not valid Ajit ASP .Net 1 04-24-2004 09:28 PM
Valid file types Aschel Kritsos ASP .Net 1 11-14-2003 05:13 PM



Advertisments