Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Are they equivalent ?

Reply
Thread Tools

Are they equivalent ?

 
 
aegis
Guest
Posts: n/a
 
      12-13-2005

Skarmander wrote:
> grid wrote:
> > Hi,
> > I have a certain situation where a particular piece of code works on a
> > particular compiler but fails on another proprietary compiler.It seems
> > to have been fixed but I just want to confirm if both statements are
> > similar :
> >
> > *((char **)v)++ == *((char **)v++)
> >
> > Where v is a pointer to an array of characters,defined as
> > char *v[];

>
> These expressions are not equivalent, and if 'v' is truly an array type (as
> opposed to a char**) they are both illegal.
>
> "*((char **)v)++" casts 'v', postincrements it and dereferences it, which is
> illegal because the operand of the increment operator may not be a cast
> expression (it's not an lvalue).
>
> "*((char **)v++)" postincrements 'v', casts it and dereferences it, which is
> illegal because the operand of the increment operator may not be of array
> type. This will work if 'v' is a char**, however, in particular if it's a
> function argument declared as "char *v[]". But in this case the cast is
> superfluous, and the statement as a whole is equivalent to simply "*v++"
> (dereferencing and postincrement have the same precedence, and associate
> right-to-left).
>


I don't know where you learned this but you need to unlearn it.
This has nothing at all to do with associativity and everything to do
with precedence.
Do not confuse prefix ++ and postfix ++ into being one and the same.
They are both different. In particular, when the prefix ++ operator is
used in
conjunction with the indirection operator, associativity is used
to disambiguate parsing. However, when postfix ++ operator is used in
conjunction
with the indirection operator, we use precedence to disambiguate the
parsing.
In this case, postfix ++ operator has higher precedence than the
indirection
operator and the same precedence as the prefix ++ operator.

> It's unclear what expression you're going for. You might also mean "v[0]++",
> which is equivalent to "(*(char **)v)++" (or simply "(*v)++").
>
> S.


I am bewildered by your statement that 'v[0]++' is equivalent to the
first
of your options listed. In what regard does 'v[0]++' imply the use of
a cast? A cast is an explicit construct. The implication of your
statement is
that the subscript operator, for some odd reason, uses a cast
to do its job. However, the standard has something quite different to
say about how the subscript operator does its job.

--
aegis

 
Reply With Quote
 
 
 
 
Skarmander
Guest
Posts: n/a
 
      12-14-2005
aegis wrote:
> Skarmander wrote:
>> grid wrote:
>>> Hi,
>>> I have a certain situation where a particular piece of code works on a
>>> particular compiler but fails on another proprietary compiler.It seems
>>> to have been fixed but I just want to confirm if both statements are
>>> similar :
>>>
>>> *((char **)v)++ == *((char **)v++)
>>>
>>> Where v is a pointer to an array of characters,defined as
>>> char *v[];

>> These expressions are not equivalent, and if 'v' is truly an array type (as
>> opposed to a char**) they are both illegal.
>>
>> "*((char **)v)++" casts 'v', postincrements it and dereferences it, which is
>> illegal because the operand of the increment operator may not be a cast
>> expression (it's not an lvalue).
>>
>> "*((char **)v++)" postincrements 'v', casts it and dereferences it, which is
>> illegal because the operand of the increment operator may not be of array
>> type. This will work if 'v' is a char**, however, in particular if it's a
>> function argument declared as "char *v[]". But in this case the cast is
>> superfluous, and the statement as a whole is equivalent to simply "*v++"
>> (dereferencing and postincrement have the same precedence, and associate
>> right-to-left).
>>

>


> I don't know where you learned this but you need to unlearn it.

<snip>

Argh, the famous C precedence lossage. Postincrement associates
left-to-right and has higher precedence than dereferencing and preincrement,
which associate right-to-left.

Honest slip-up. I don't think I need to retake C 101 just yet. Thanks
for pointing this out.

<snip>
>> It's unclear what expression you're going for. You might also mean "v[0]++",
>> which is equivalent to "(*(char **)v)++" (or simply "(*v)++").
>>

>
> I am bewildered by your statement that 'v[0]++' is equivalent to the
> first of your options listed. In what regard does 'v[0]++' imply the use
> of a cast?


It does not. In the particular context given, these expressions are
equivalent. The sole reason it is provided is for comparison.

> A cast is an explicit construct. The implication of your statement is
> that the subscript operator, for some odd reason, uses a cast to do its
> job.


This was not my intent, and I apologize for being unclear.

S.
 
Reply With Quote
 
 
 
 
Jordan Abel
Guest
Posts: n/a
 
      12-14-2005
On 2005-12-14, Skarmander <(E-Mail Removed)> wrote:
> aegis wrote:
>> Skarmander wrote:
>>> grid wrote:
>>>> Hi,
>>>> I have a certain situation where a particular piece of code works on a
>>>> particular compiler but fails on another proprietary compiler.It seems
>>>> to have been fixed but I just want to confirm if both statements are
>>>> similar :
>>>>
>>>> *((char **)v)++ == *((char **)v++)
>>>>
>>>> Where v is a pointer to an array of characters,defined as
>>>> char *v[];
>>> These expressions are not equivalent, and if 'v' is truly an array type (as
>>> opposed to a char**) they are both illegal.
>>>
>>> "*((char **)v)++" casts 'v', postincrements it and dereferences it, which is
>>> illegal because the operand of the increment operator may not be a cast
>>> expression (it's not an lvalue).
>>>
>>> "*((char **)v++)" postincrements 'v', casts it and dereferences it, which is
>>> illegal because the operand of the increment operator may not be of array
>>> type. This will work if 'v' is a char**, however, in particular if it's a
>>> function argument declared as "char *v[]". But in this case the cast is
>>> superfluous, and the statement as a whole is equivalent to simply "*v++"
>>> (dereferencing and postincrement have the same precedence, and associate
>>> right-to-left).
>>>

>>

>
>> I don't know where you learned this but you need to unlearn it.

> <snip>
>
> Argh, the famous C precedence lossage. Postincrement associates
> left-to-right and has higher precedence than dereferencing and preincrement,
> which associate right-to-left.


postincrement and preincrement on the same expression is a constraint
violation [as the result of either is not an lvalue] violation, so it
doesn't particularly matter which way they associate.
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      12-17-2005
>grid wrote:
>> I have a certain situation where a particular piece of code works on a
>> particular compiler but fails on another proprietary compiler. ...
>>
>> *((char **)v)++

[ and ]
>> *((char **)v++)
>>
>> Where v is a pointer to an array of characters,defined as
>> char *v[];


[I suspect it is not in fact of type "array of UNKNOWN_SIZE of
pointer to char". As the speculation elsethread runs, perhaps this
is a function parameter, so that v really has type "pointer to
pointer to char".]

In article <439ef26e$0$11069$(E-Mail Removed)4all.nl>
Skarmander <(E-Mail Removed)> wrote:
>These expressions are not equivalent, and if 'v' is truly an array type (as
>opposed to a char**) they are both illegal.


Indeed. Your next few paragraphs, however, suffer somewhat from
the use of pronouns whose referents are not quite clear:

>"*((char **)v)++" casts 'v', postincrements it and dereferences it,


Specifically, this binds / breaks down as:

(char **) [a cast]
v [puts the variable "v" in a value context]
( )++ [post-increment the parenthesized thing]
* [apply unary indirection to result of post-increment]

Hence the "it" that is post-incremented is the result of a cast,
which is a value (rather than an object); the "it" that is
"dereferenced" (followed via the unary * operator) is the
result of the post-increment.

>which is illegal because the operand of the increment operator may
>not be a cast expression (it's not an lvalue).


>"*((char **)v++)" postincrements 'v', casts it and dereferences it,


In this case, the "it"s (and the expression overall) bind as:

v++ [post-increment the object (not value) v]
(char **) [cast, i.e., convert value as if by assignment]
( ) [technically-unnecessary parentheses]
* [apply unary indirection to result of cast]

>which is illegal because the operand of the increment operator may
>not be of array type.


Indeed.

>This will work if 'v' is a char**, however, in particular if it's a
>function argument declared as "char *v[]". But in this case the cast is
>superfluous, and the statement as a whole is equivalent to simply "*v++"
>(dereferencing and postincrement have the same precedence, and associate
>right-to-left).


And this, too, is all quite correct. If v really has type "char **",
just write "*v++".

>It's unclear what expression you're going for. You might also mean
>"v[0]++", which is equivalent to "(*(char **)v)++" (or simply "(*v)++").


I think I would write this as v[0]++ in most cases, myself.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      12-18-2005
On Tue, 13 Dec 2005 20:50:35 +0530, grid <(E-Mail Removed)> wrote:

>Hi,
> I have a certain situation where a particular piece of code works on a
>particular compiler but fails on another proprietary compiler.It seems
>to have been fixed but I just want to confirm if both statements are
>similar :
>
>*((char **)v)++ == *((char **)v++)
>
>Where v is a pointer to an array of characters,defined as
>char *v[];
>
>I am passing "v" to a function expecting a char * .


If v is defined as an "object" (as opposed to a function parameter) of
type array of pointers to char, then you cannot pass it to a function
expecting a pointer to char.

In the context of a function pointer, an array name evaluates to the
address of the first element of the array with type pointer to element
type. Therefore v evaluates to &v[0] with type pointer to pointer to
char. There is no implicit conversion between char** and char*.

If your compiler is not issuing a diagnostic for your function call,
either up the warning level or get one that isn't broken.

While adding a cast will eliminate the diagnostic, it will also lead
to undefined, or at the very least unexpected, behavior when the
function executes. If the function dereferences the pointer, it
expects to find a char. In this case, it will actually find the first
byte of an address. What happens after that will probably not be
pleasant.


<<Remove the del for email>>
 
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
Tokina, Sigma, Tamron --- Are they equivalent in quality? Dave Digital Photography 40 04-11-2007 12:34 PM
Re: "memset" vs "= {0}"...Are they equivalent if your initializing variables? C++ 1 09-23-2004 02:03 PM
Re: "memset" vs "= {0}"...Are they equivalent if your initializing variables? C++ 0 09-23-2004 01:28 PM
"memset" vs "= {0}"...Are they equivalent if your initializing variables? Nollie@runtime.com C++ 17 09-22-2004 06:06 PM
they turn, they power, they make nice pics Keith and Jenn Z. Digital Photography 0 09-21-2003 04:16 AM



Advertisments