tricky use of sizeof [explanation wanted]

G

goacross

i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

thanks
 
G

goacross

i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

thanks

I run the program in vc :)
 
J

junky_fellow

i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

thanks

This is becuase,
sizeof('h')[p] will return the size of the expression ('h')[p] which
will always be 1 as the p is pointer to char.
 
Z

Zara

i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

Compare these two expressions:

char n=(sizeof('h'))[p]; (1)

char n=sizeof(('h')[p]); (2)

Your second expression is being interpreted as (2), and what you
wanted was (1)

The problem lies in sizeof be¡ing greedy when it refers to an object
and not to a type

Best regrads,

Zara
 
F

Flash Gordon

Zara wrote, On 13/09/07 07:00:
i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

Compare these two expressions:

char n=(sizeof('h'))[p]; (1)

This is the same as
char n = (sizeof 'h')[p];
This will still not do what the OP expected in C although it will in
C++. This is because a character literal like 'h' has type int in C
(probably 4 on the OPs system, although it could be any other number)
whereas in C++ it would have type char.
char n=sizeof(('h')[p]); (2)

Your second expression is being interpreted as (2), and what you
wanted was (1)

The problem lies in sizeof be¡ing greedy when it refers to an object
and not to a type

Also note that sizeof is an operator, NOT a function. This is why you
can do "sizeof expression" rather than "sizeof(expression)" and is
probably also part of the OPs confusion.
 
G

goacross

i found something tricky this morning.
char *p="abc";
1. char m=1[p];// m='b'
2. char n=sizeof('h')[p]; // n=1;
I guess the reason of 1is,
1+p=p+1; so the same as p[1];
but why the seemed same thing doesn't work on case 2?

Compare these two expressions:

char n=(sizeof('h'))[p]; (1)

char n=sizeof(('h')[p]); (2)

Your second expression is being interpreted as (2), and what you
wanted was (1)

The problem lies in sizeof be¡ing greedy when it refers to an object
and not to a type

Best regrads,

Zara

Thank you all.
It's clear now. :)
 
A

Army1987

i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

sizeof('h') is sizeof(int). If it is four, 4+"abc" will point past
the end of the string, so dereferencing it, even implicitly with
[], will cause UB. If sizeof(int) is > 4, even pointer arithmetic
itself will cause UB, even if you don't dereference. If
sizeof(int) < 4, n will be 'b', 'c', or 0.
 
B

Barry Schwarz

i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

*(1+p) = *(p+1) = p[1] = 1[p].


Remove del for email
 
B

Barry Schwarz

i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

sizeof('h') is sizeof(int). If it is four, 4+"abc" will point past
the end of the string, so dereferencing it, even implicitly with
[], will cause UB. If sizeof(int) is > 4, even pointer arithmetic
itself will cause UB, even if you don't dereference. If
sizeof(int) < 4, n will be 'b', 'c', or 0.

Except for variable length arrays (not germane to this thread), sizeof
never evaluates its operand. Consequently, nothing gets dereferenced.
The operand is analyzed only to determine its type, not whether it
actually exists.


Remove del for email
 
A

Army1987

2. char n=sizeof('h')[p]; // n=1;
sizeof('h') is sizeof(int). If it is four, 4+"abc" will point past
the end of the string, so dereferencing it, even implicitly with
[], will cause UB. If sizeof(int) is > 4, even pointer arithmetic
itself will cause UB, even if you don't dereference. If
sizeof(int) < 4, n will be 'b', 'c', or 0.

Except for variable length arrays (not germane to this thread), sizeof
never evaluates its operand. Consequently, nothing gets dereferenced.
The operand is analyzed only to determine its type, not whether it
actually exists.

Yeah, damned syntax... sizeof('h')[p] means sizeof(('h')[p]), not
(sizeof('h'))[p] as I was thinking when I wrote that reply...
 
C

Charlie Gordon

Barry Schwarz said:
i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

*(1+p) = *(p+1) = p[1] = 1[p].

While your demonstration clears some of the OP's interrogations, it does not
account for 2.

Let's delve into this tricky problem:

sizeof('h')[p] is a very different biest from (sizeof('h'))[p]

in C++ (sizeof('h'))[p] would do the same thing as sizeof(char))[p] yield
1[p] which is 'b'

in C however sizeof('h') is the same as sizeof(int) which is implementation
defined.

on some cumbersome DSPs, sizeof('h') is 1 and (sizeof(char))[p] evaluates
to 'b'
on MSDOS 16 bits, sizeof('h') is 2 and (sizeof(char))[p] evaluates to 'c'
I do not know any system on which sizeof('h') is 3, but that is not
impossible. (sizeof(char))[p] would then equal 0
on most modern systems sizeof('h') is at least 4 and (sizeof(char))[p]
invokes undefined behaviour.

on the other hand sizeof('h')[p] does not evaluate as sizeof(char)[p] nor
sizeof(int)[p], both syntax errors.

Indeed sizeof('h')[p] evaluates as sizeof (('h')[p]).

Or more simply: sizeof 'h'[p] which is equivalent to sizeof p['h']

I can hear purists argue that p points to a 4 byte array and 'h' is most
likely larger than 4 so p['h'] is an invalid pointer reference. Yet the
expression argument to sizeof does not get evaluated, only its type is
determined. The type here is char. sizeof(char) is 1 by definition. QED.

Note that you can further mesmerize you audience by defining this inoccuous
looking macro:

#define sizeof(x) (sizeof(x))

What becomes of sizeof('h')[p] in this case ?

What other side effects does this macro have ?
 
C

Charlie Gordon

Barry Schwarz said:
i found something tricky this morning.

char *p="abc";

1. char m=1[p];// m='b'

2. char n=sizeof('h')[p]; // n=1;

I guess the reason of 1is,

1+p=p+1; so the same as p[1];

but why the seemed same thing doesn't work on case 2?

sizeof('h') is sizeof(int). If it is four, 4+"abc" will point past
the end of the string, so dereferencing it, even implicitly with
[], will cause UB. If sizeof(int) is > 4, even pointer arithmetic
itself will cause UB, even if you don't dereference. If
sizeof(int) < 4, n will be 'b', 'c', or 0.

No, you are not on the right track.
Except for variable length arrays (not germane to this thread), sizeof
never evaluates its operand. Consequently, nothing gets dereferenced.
The operand is analyzed only to determine its type, not whether it
actually exists.

sizeof does not evaluate its operand in variable length arrays either, the
evaluation is done at run-time to determine the size of the operand not
known at compile time, but that does not involve evaluating the operand.

The rest is true but unrelated to the previous post (erroneous) answer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top