Question about the *= (and similar) operator

S

spibou

Keith said:
No, it was a question about operator precedence (actually about how
expressions are parsed, since the standard doesn't talk about
precedence as such). The semantics of the expression follow from the
way it's parsed (and from the semantics of the operations themselves).

Perhaps that's how you read it but precedence was not what I was
confused
about. See below.
 
S

spibou

Rafael said:
Well , I saw my question as one about semantics rather than operator
precedence.
Are you saying keith didn't answer your question?[/QUOTE]

By the time I read Ketih's post I had read others which had answered my
question. I'm not sure if Keith's post would have done it on its own. I
was
simply saying that he didn't understand what I was confused about.
 
S

spibou

Giannis said:
ISO C99 draft (N1124) §6.5.16.2:
A compound assignment of the form E1 op = E2 differs from the simple
assignment expression E1 = E1 op (E2) only in that the lvalue E1 is
evaluated only once.

Although that answers my question I'm confused about the "only once"
part. How many times is E1 evaluated in "E1 = E1 op (E2)" ? Or to be
more specific how many times is "a" evaluated in "a = a * (b+c)" ?
 
T

Thomas J. Gritzan

Although that answers my question I'm confused about the "only once"
part. How many times is E1 evaluated in "E1 = E1 op (E2)" ? Or to be
more specific how many times is "a" evaluated in "a = a * (b+c)" ?

Well, a appears two times, so its evaluated two times. Simple?

Thomas
 
S

spibou

Thomas said:
Well, a appears two times, so its evaluated two times. Simple?

Nope ! Perhaps I have the wrong idea about what "evaluated" means.
Could you explain that ? Consider something simpler first: "a=1". What
is the evaluation of "a" in this case ?
 
K

Keith Thompson

Although that answers my question I'm confused about the "only once"
part. How many times is E1 evaluated in "E1 = E1 op (E2)" ? Or to be
more specific how many times is "a" evaluated in "a = a * (b+c)" ?

In "a = a * (b + c)", a is evaluated twice -- but in this case it
doesn't matter (unless a happens to be volatile).

This becomes more relevant if the expression has side effects.

#include <stdio.h>

int func(char *message)
{
printf("In func(\"%s\")\n", message);
return 0;
}

int main(void)
{
int arr[1] = { 0 };

arr[func("Not using *=")] = arr[func("Not using *=")] * 42;
arr[func("Using *=")] *= 42;

return 0;
}

This prints:

In func("Not using *=")
In func("Not using *=")
In func("Using *=")
 
A

Andrew Poelstra

I don't see how the above statements follow from what I said.


I don't feel that the words pedantic and suspicious apply at all to
what I said.


These qustions are outside the topic of the thread.


I suggested the possibility that the choice between *only 2*
interpretations
could be up to individual implementations. Even without such a
restriction
I don't see how it would have anything to do with one's ability to rise
to the
level of basic user.
This is a basic question. If you can't understand it, (or if implementation
differences make it impossible to understand it), you can't become a basic
user.
I can't imagine what insight you think it would offer but I'm pretty
sure it wouldn't answer my question. In any case why don't you run
the experiment and tell us what insight you gained ?

It will answer your question, and Chris won't run the experiment because
he knows C, and already knows the answer. He's merely encouraging you to
figure it out yourself, and hence learn to teach yourself.

If you give a man a fish, he'll eat for a day...
 
S

spibou

Keith said:
In "a = a * (b + c)", a is evaluated twice -- but in this case it
doesn't matter (unless a happens to be volatile).

I take it that if it's volatile then its value may change between
evaluations.
This becomes more relevant if the expression has side effects.

#include <stdio.h>

int func(char *message)
{
printf("In func(\"%s\")\n", message);
return 0;
}

int main(void)
{
int arr[1] = { 0 };

arr[func("Not using *=")] = arr[func("Not using *=")] * 42;
arr[func("Using *=")] *= 42;

return 0;
}

This prints:

In func("Not using *=")
In func("Not using *=")
In func("Using *=")

That was very enlightening. Thank you.

Andrew said:
This is a basic question. If you can't understand it, (or if implementation
differences make it impossible to understand it), you can't become a basic
user.

I understand the question and I understand straightforward answers to
the question. I have written a fair amount of above basic programmes
in C therefore it has been possible for me to become more than a basic
user of the language without knowing the answer to the question.
It will answer your question, and Chris won't run the experiment because
he knows C, and already knows the answer. He's merely encouraging you to
figure it out yourself, and hence learn to teach yourself.

Since you're claiming that it would answer my question can you explain
what
series of arguments starting from the result of the experiment and I
don't know
which other premises would lead me to conclude that the behaviour I
observed
was standard as opposed to implementation defined ?
Otherwise , Chris may know the answer to the question but he claimed
that the
experiment would offer me "far more insight". I don't know what this
substantial
amount of insight is supposed to be. I'm not even sure whether an
answer to my
question is supposed to be part of this insight.
The replies in the thread have offered me insight. The reply by Keith
above for
example or the quote form the standard or the comparison between macros
and
operators given in a different post (not quoted here). I wouldn't have
gotten any
of that from an experiment even if it would have answered my question
and I
don't believe it would have.
If you give a man a fish, he'll eat for a day...

So you're saying that writing and running a small C programme would
teach me
about fishing. But I'm a city person you see , I don't fish. If I want
fish I just go
to the supermarket.

Spiros Bousbouras
 
K

Keith Thompson

Keith Thompson wrote: [...]
In "a = a * (b + c)", a is evaluated twice -- but in this case it
doesn't matter (unless a happens to be volatile).

Yes, that too. Volatility goes both ways: external mechanisms can
change a volatile variable's behind the program's back, and any access
(either a read or a write) of a volatile variable is considered a side
effect, so it must actually happen. Given:

{
volatile int x;
int y;
x = 10;
x = 20;
y = x;
printf("y = %d\n", y);
}

the generated code must actually store the values 10 and 20 to x, and
then read x to store its value in y. Without the "volatile", the
compiler could legally entire chunk of code to:

puts("y = 20");

(In practice, there's no good reason to apply "volatile" to an auto
object; more commonly it might be applied to an object at a specified
address, such as a hardware register of some kind.)
 
J

jaysome

Keith Thompson wrote: [...]
In "a = a * (b + c)", a is evaluated twice -- but in this case it
doesn't matter (unless a happens to be volatile).

Yes, that too. Volatility goes both ways: external mechanisms can
change a volatile variable's behind the program's back, and any access
(either a read or a write) of a volatile variable is considered a side
effect, so it must actually happen. Given:

{
volatile int x;
int y;
x = 10;
x = 20;
y = x;
printf("y = %d\n", y);
}

the generated code must actually store the values 10 and 20 to x, and
then read x to store its value in y. Without the "volatile", the
compiler could legally entire chunk of code to:

puts("y = 20");

(In practice, there's no good reason to apply "volatile" to an auto
object; more commonly it might be applied to an object at a specified
address, such as a hardware register of some kind.)

I can't think of any reason why a volatile auto object that is not a
pointer and is not pointed to by a suitably typed pointer could ever
be useful. Sure, C may allow that, but what use could it ever be?
 
K

Keith Thompson

jaysome said:
[...]
(In practice, there's no good reason to apply "volatile" to an auto
object; more commonly it might be applied to an object at a specified
address, such as a hardware register of some kind.)

I can't think of any reason why a volatile auto object that is not a
pointer and is not pointed to by a suitably typed pointer could ever
be useful. Sure, C may allow that, but what use could it ever be?

Possibly you might pass the address of the object to some
system-specific routine that causes the system to treat the object in
some odd way. I suppose that's nearly equivalent to your "pointed to
by a suitably typed pointer".
 
N

Nick Keighley

Chris said:
Sorry, politely, this is bordering on the absurd.

no. He is being entirely correct
You do not trust anything you observe from experiments,

well experiments on implementations don't necessarily tell you if you
are
observing standard behaviour or implementation behaviour.

*0 = 1;
i= 2; j = i++ + i++;
k = 1 / 0;

They may all give a particular result on a particular implementation
you do not trust anything you get from a reply here,

? then why was he asking? clc is pretty good at coming to some sort
of concensus, if not definitive answer.
you do not trust anything you investigate to be conforming.

well it's a base assumption
OK, it's your choice to be so suspicious and pedantic, but it's unclear
what you, or the OP, should ever trust.

Will you trust your own interpretation of the standard?

the standard is a formal document and in principal can give
unambiguous,
interpretation-free answers
Will you trust anyone's interpretation of the standard?

someone else may be better at reading the formal langauge of the
standard
than the OP. Note the OP was asking what the standard said so
presumably
he hadn't read it.
And if you do trust your own or anyone else's interpretation of the standard,
how did you gain that trust?

reading the standard then asking well informed people if your
interpreataion is
correct. After clc you could go to comp.lang.c.std where people form
the ISO
standard actually hang out.
If every commodity compiler such as MS-Studio or gcc chose to implement
the above assignment in an implementation defined fashion, then how is
anyone to rise to the level of even a basic user?

well presumably MS and GNU *try* to be standards compliant.
Given the nature of the OP's original question, it's clear to anyone
that a basic experiment, for varying values of a, b, and c, will reveal
far more insight than all the anal reflection in the world.

with respect, nonsense.


--
Nick Keighley

-pedantic
This option is not intended to be useful; it exists only to satisfy
pedants who would otherwise claim that GNU CC fails to support the
ANSI standard.
(Using and Porting GNU CC)

in comp.lang.c, the very people most capable of making the inference
are those least likely to make it. This newsgroup considers pedantry
to be an art form.
Richard Heathfield
 
G

Guest

jaysome said:
I can't think of any reason why a volatile auto object that is not a
pointer and is not pointed to by a suitably typed pointer could ever
be useful. Sure, C may allow that, but what use could it ever be?

It can be necessary for some uses of longjmp.
 
R

Richard Tobin

Well, a appears two times, so its evaluated two times. Simple?
[/QUOTE]
Nope ! Perhaps I have the wrong idea about what "evaluated" means.
Could you explain that ? Consider something simpler first: "a=1". What
is the evaluation of "a" in this case ?

If a is an ordinary variable, then evaluating it doesn't amount to
much. But if a is an expression such as array[index++], then
evaluating it has side effects and these will happen twice in
array[index++] = array[index++] + 1 but only once in array[index++] += 1.

-- Richard
 
R

Richard Tobin

Keith Thompson said:
No, it was a question about operator precedence

Perhaps not...

(1) C operators work like an infix notation for functions
(2) operator precedence determines which arguments go with with function.

The OP seemed to have doubts about the truth of (1) - he gave a
possibility that would imply they worked like macros - so he hadn't
got to the point where his question would be about operator
precedence.

-- Richard
 
G

Guest

jaysome said:
Can you give an example?

#include <stdio.h>
#include <setjmp.h>

int main(void) {
jmp_buf buf;
#if 0
volatile
#endif
int x = 0;
if(setjmp(buf) == 0) {
x = 1;
longjmp(buf, 0);
}
printf("%d\n", x);
}

My compiler assumes that since longjmp() can't ever return, printf()
will always print 0, and doesn't re-read x. This is a legitimate
optimisation unless volatile is used.
 
J

James Dow Allen

In the statement "a *= expression" is expression assumed to be
parenthesized ? For example if I write "a *= b+c" is this the same
as "a = a * (b+c)" or "a = a * b+c" ?

Two correct answers have already been offered:
(1) Compare precedence of " *= " with " + ".
(2) Write a test program and find out.

I'll offer a little "meta-discussion".

First, is it really conceivable that someone would invent a language
in which
a *= b+c
*really* becomes
a = (a*b) + c
?

If you really suspected this might be the case, then you either have
*very*
poor intuition about expression "design" or you've somehow concluded
that the C language was designed by a sadist, who's trying to trick you
with peculiar rules.

You indicate that you didn't want to experiment out of fear the result
was
compiler dependent! Again, if you could imagine that such a simple
expression
could be compiler dependent you've acquired a poor impression of C.

Frankly, postings in this newsgroup may be partly to blame for creating
the misconception that (any but rarish) C expressions are ambiguous.
For example, in another thread I introduced an interesting issue, but
added a peculiar formula, which relied on function pointers all
smelling
the same, for humorous effect. The interesting part of the post was
ignored, but several responses, while acknowledging that function
pointers
probably always smell the same on all present implementations, focussed
on the question of whether this was spelled out in the Standard.

C started out with a philosophy that is the antithesis of languages
like C++.
In the "old days", C textbooks happily acknowledged that some details
were machine-dependent and enocuraged experimentation if you weren't
sure how your machine worked!

Standardization has its purpose, but I think you'll be a happier and
more
successful C programmer if you can acquire some of the more
"old fashioned" C spirit.

Take this message to heart and soon you'll be doing things much harder
than
a *= b+c
without needing help from Usenet.

James Dow Allen
 
C

CBFalconer

James said:
.... snip ...

First, is it really conceivable that someone would invent a
language in which
a *= b+c
*really* becomes
a = (a*b) + c
?

If you really suspected this might be the case, then you either
have *very* poor intuition about expression "design" or you've
somehow concluded that the C language was designed by a sadist,
who's trying to trick you with peculiar rules.

Well? You haven't been doing C for long, I see :)

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
K

Kenneth Brody

James Dow Allen wrote:
[...]
First, is it really conceivable that someone would invent a language
in which
a *= b+c
*really* becomes
a = (a*b) + c
?

"Conceivable"? Of course!

"Likely, in a 'real-world' language"? Probably not.

Check out languages like INTERCAL and BrainF*** if you want to see
just what sort of languages people come up with.

[...]

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top