Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
On 05/23/24 7:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
The question is meaningless without knowing the types of objects
involved. It has no specific answer
On 05/23/24 7:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
The question is meaningless without knowing the types of objects
involved. It has no specific answer
On 6/18/2024 8:53 PM, Andrey Tarasevich wrote:
On 05/23/24 7:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
The question is meaningless without knowing the types of objects
involved. It has no specific answer
If it works correctly for int then it is
syntactically correct:
int x = 1;
int f = 1;
x = 1 * (2 * 3);
++f could be defined as exit(0) for some UDT.
On 6/21/24 5:55 PM, olcott wrote:
On 6/18/2024 8:53 PM, Andrey Tarasevich wrote:
On 05/23/24 7:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
The question is meaningless without knowing the types of objects
involved. It has no specific answer
If it works correctly for int then it is
syntactically correct:
int x = 1;
int f = 1;
x = 1 * (2 * 3);
++f could be defined as exit(0) for some UDT.
But, the DEFINITON of ++ doesn't requring that one of the f's are incremented first, then you use the value, then the othero one. (unless
the rules were actually changed).
On 6/21/2024 5:10 PM, Richard Damon wrote:
On 6/21/24 5:55 PM, olcott wrote:
On 6/18/2024 8:53 PM, Andrey Tarasevich wrote:
On 05/23/24 7:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
The question is meaningless without knowing the types of objects
involved. It has no specific answer
If it works correctly for int then it is
syntactically correct:
int x = 1;
int f = 1;
x = 1 * (2 * 3);
++f could be defined as exit(0) for some UDT.
But, the DEFINITON of ++ doesn't requring that one of the f's are
incremented first, then you use the value, then the othero one.
(unless the rules were actually changed).
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
On 6/21/2024 5:10 PM, Richard Damon wrote:
On 6/21/24 5:55 PM, olcott wrote:
On 6/18/2024 8:53 PM, Andrey Tarasevich wrote:
On 05/23/24 7:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
The question is meaningless without knowing the types of objects
involved. It has no specific answer
If it works correctly for int then it is
syntactically correct:
int x = 1;
int f = 1;
x = 1 * (2 * 3);
++f could be defined as exit(0) for some UDT.But, the DEFINITON of ++ doesn't requring that one of the f's are
incremented first, then you use the value, then the othero
one. (unless the rules were actually changed).
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
olcott <polcott333@gmail.com> writes:
On 6/21/2024 5:10 PM, Richard Damon wrote:
On 6/21/24 5:55 PM, olcott wrote:
On 6/18/2024 8:53 PM, Andrey Tarasevich wrote:
On 05/23/24 7:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
The question is meaningless without knowing the types of objects
involved. It has no specific answer
If it works correctly for int then it is
syntactically correct:
int x = 1;
int f = 1;
x = 1 * (2 * 3);
Yes, it's syntactically valid, but that wasn't the question.
++f could be defined as exit(0) for some UDT.But, the DEFINITON of ++ doesn't requring that one of the f's are
incremented first, then you use the value, then the othero
one. (unless the rules were actually changed).
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
We don't have to assume anything. The meaning of "*=" is well known
(and you left out the fact that x is evaluated only once).
It doesn't have implementation-defined behavior. It has undefined
behavior. The C++ standard says so:
If a side effect on a memory location is unsequenced relative to
either another side effect on the same memory location or a value
computation using the value of any object in the same memory
location, and they are not potentially concurrent, the behavior is
undefined.
If x and f are objects of type int, then the evaluation of `++f * ++f`
has undefined behavior because the two modifications of f are
unsequenced. There isn't some limited number of possible behaviors.
The standard says nothing about what happens when the expression is evaluated.
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by itself, undefined behavior,
independent of what larger expression it might be
part of. "implementation-defined behavior" is defined by the standard as "behavior, for a well-formed program construct and correct data, that
depends on the implementation and that each implementation documents"
(3.13). Since this program is not well formed, implementations have no obligation to document what it's behavior will be, so it cannot be implementation-defined behavior.
Repeating what I said in an earlier message (with one minor correction):
"Except where noted, evaluations of operands of individual operators and
of subexpressions of individual expressions are unsequenced." (6.9.1p10)
Both ++f expressions are sub-expressions of the multiplication
expression. Thus, the executions are unsequenced, which is not, in
itself, a problem. However, they both have a side effect on the same
memory location, and that is a problem, because that same clause goes on
to say:
"If a side effect on a memory location (6.7.1) is unsequenced relative
to either another side effect on the same memory location or a value computation using the value of any object in the same memory location,
and they are not potentially concurrent (6.9.2), the behavior is undefined."
These two expressions are not potentially concurrent: they are in the
same expression, so they must be in the same thread, and if they are in
a signal handler, they must both be in the same signal handler.
Therefore, the expression ++f * ++f has undefined behavior.
That is weird I wold have chosen left to right sequence.
I thought that the order of arithmetic operations specifies
left to right sequence.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by itself,
undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
olcott <polcott333@gmail.com> writes:
[...]
That is weird I wold have chosen left to right sequence.
I thought that the order of arithmetic operations specifies
left to right sequence.
You may well have thought that. You were wrong. Do you understand that
now?
On 22/06/2024 06:02, olcott wrote:
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by itself,
undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
Some programming languages define the order of evaluation for
subexpressions like this.ÿ Neither C nor C++ do (except for specific operators, which do not include multiplication).
It doesn't really matter what you consider "natural" or not - it matters what the standards say.
On 6/22/2024 1:18 AM, Keith Thompson wrote:
olcott <polcott333@gmail.com> writes:
[...]
That is weird I wold have chosen left to right sequence.
I thought that the order of arithmetic operations specifies
left to right sequence.
You may well have thought that.ÿ You were wrong.ÿ Do you understand that
now?
"x *= ++f * ++f"
int x = 5;
int y = 3;
For the calculation is question is seems to make no difference to the result.
x = 5 * (4 * 5)
x = 5 * (5 * 4)
On 6/22/2024 6:09 AM, David Brown wrote:
On 22/06/2024 06:02, olcott wrote:It would be bad for the standards to be counter-intuitive.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by itself, >>>> undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
Some programming languages define the order of evaluation for
subexpressions like this.ÿ Neither C nor C++ do (except for specific
operators, which do not include multiplication).
It doesn't really matter what you consider "natural" or not - it
matters what the standards say.
On 6/22/24 8:38 AM, olcott wrote:
On 6/22/2024 1:18 AM, Keith Thompson wrote:
olcott <polcott333@gmail.com> writes:
[...]
That is weird I wold have chosen left to right sequence.
I thought that the order of arithmetic operations specifies
left to right sequence.
You may well have thought that.ÿ You were wrong.ÿ Do you understand that >>> now?
"x *= ++f * ++f"
int x = 5;
int y = 3;
For the calculation is question is seems to make no difference to the
result.
x = 5 * (4 * 5)
x = 5 * (5 * 4)
In this case no, but if the operation was - it would,
And, as pointed out there is no requirement on the ordering of even the sub-parts except determinism (we can't use a value we haven't computed
yet). This means the ++ can be interleaved.
And, because of the EXPLICIT requirement on updates to a value needing
to be ordered to avoid undefined behavior,
the compiler, seeing that
Undefined Behavior exist there can do ANYTHING it wants with that code.
On 6/22/2024 8:45 AM, Richard Damon wrote:
On 6/22/24 8:38 AM, olcott wrote:
On 6/22/2024 1:18 AM, Keith Thompson wrote:
olcott <polcott333@gmail.com> writes:
[...]
That is weird I wold have chosen left to right sequence.
I thought that the order of arithmetic operations specifies
left to right sequence.
You may well have thought that.ÿ You were wrong.ÿ Do you understand
that
now?
"x *= ++f * ++f"
int x = 5;
int y = 3;
For the calculation is question is seems to make no difference to the
result.
x = 5 * (4 * 5)
x = 5 * (5 * 4)
In this case no, but if the operation was - it would,
And, as pointed out there is no requirement on the ordering of even
the sub-parts except determinism (we can't use a value we haven't
computed yet). This means the ++ can be interleaved.
And, because of the EXPLICIT requirement on updates to a value needing
to be ordered to avoid undefined behavior,
In other words you fail to comprehend that: (5 * 4) == (4 * 5)
the compiler, seeing that Undefined Behavior exist there can do
ANYTHING it wants with that code.
On 6/22/2024 6:09 AM, David Brown wrote:
On 22/06/2024 06:02, olcott wrote:It would be bad for the standards to be counter-intuitive.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by itself, >>>> undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
Some programming languages define the order of evaluation for
subexpressions like this.ÿ Neither C nor C++ do (except for specific
operators, which do not include multiplication).
It doesn't really matter what you consider "natural" or not - it
matters what the standards say.
On 22/06/2024 14:40, olcott wrote:
On 6/22/2024 6:09 AM, David Brown wrote:
On 22/06/2024 06:02, olcott wrote:It would be bad for the standards to be counter-intuitive.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by
itself,
undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
Some programming languages define the order of evaluation for
subexpressions like this.ÿ Neither C nor C++ do (except for specific
operators, which do not include multiplication).
It doesn't really matter what you consider "natural" or not - it
matters what the standards say.
People's "intuition" varies wildly.ÿ Pretty much any definition would be counter-intuitive to someone.ÿ That's why language standards try to have precise definitions, rather than just saying "it all works pretty much
like you'd expect".
We realise the definition of C and C++ expression evaluation does not
match what you thought was "intuitive".ÿ That does not matter - it would
not matter even if lots of C and C++ programmers agreed with you.ÿ What matters for these languages is what their standards /say/.ÿ That way, we
can look at clear facts written in official documents, rather than
trying to rely on what random people think about to be how they imagine things ought to be.
You can happily feel that C would be better if evaluation order were strictly define.ÿ Some people will agree with that, others will disagree
- but it will not make a blind bit of difference to the actual /facts/
of the matter.
On 6/22/2024 9:52 AM, David Brown wrote:
On 22/06/2024 14:40, olcott wrote:
On 6/22/2024 6:09 AM, David Brown wrote:
On 22/06/2024 06:02, olcott wrote:It would be bad for the standards to be counter-intuitive.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your >>>>>> premise has to do with it. The expression ++f * ++f has, all by
itself,
undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
Some programming languages define the order of evaluation for
subexpressions like this.ÿ Neither C nor C++ do (except for specific
operators, which do not include multiplication).
It doesn't really matter what you consider "natural" or not - it
matters what the standards say.
People's "intuition" varies wildly.ÿ Pretty much any definition would
be counter-intuitive to someone.ÿ That's why language standards try to
have precise definitions, rather than just saying "it all works pretty
much like you'd expect".
We realise the definition of C and C++ expression evaluation does not
match what you thought was "intuitive".ÿ That does not matter - it
would not matter even if lots of C and C++ programmers agreed with
you.ÿ What matters for these languages is what their standards /say/.
That way, we can look at clear facts written in official documents,
rather than trying to rely on what random people think about to be how
they imagine things ought to be.
You can happily feel that C would be better if evaluation order were
strictly define.ÿ Some people will agree with that, others will
disagree - but it will not make a blind bit of difference to the
actual /facts/ of the matter.
Then make the rule strict left to right unless otherwise specified.
int x = 2 + 3 * 5; // is otherwise specified by operator precedence.
On 6/22/24 8:40 AM, olcott wrote:[...]
On 6/22/2024 6:09 AM, David Brown wrote:
On 22/06/2024 06:02, olcott wrote:It would be bad for the standards to be counter-intuitive.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by
itself,
undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
Some programming languages define the order of evaluation for
subexpressions like this.ÿ Neither C nor C++ do (except for specific
operators, which do not include multiplication).
It doesn't really matter what you consider "natural" or not - it
matters what the standards say.
No, the Standards are to define the "contract" between the programmer
and the implementations.
C (and to a lesser extent C++) were envisioned as "High Performance" languages designed to get efficiencies of code close to what could be created with pure assembly language.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your
premise has to do with it. The expression ++f * ++f has, all by itself,
undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
On 6/22/2024 1:18 AM, Keith Thompson wrote:
olcott <polcott333@gmail.com> writes:
[...]
That is weird I wold have chosen left to right sequence.You may well have thought that. You were wrong. Do you understand
I thought that the order of arithmetic operations specifies
left to right sequence.
that now?
"x *= ++f * ++f"
int x = 5;
int y = 3;
For the calculation is question is seems to make no difference to the
result.
x = 5 * (4 * 5)
x = 5 * (5 * 4)
Then make the rule strict left to right unless otherwise specified.
int x = 2 + 3 * 5; // is otherwise specified by operator precedence.
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
On 5/23/2024 9:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
For that specific case the result would seem to be identical
no matter the sequence of the incrementations for int type: f.
I might not understand this fully.
On 6/22/24 8:38 AM, olcott wrote:
On 6/22/2024 1:18 AM, Keith Thompson wrote:
olcott <polcott333@gmail.com> writes:
[...]
That is weird I wold have chosen left to right sequence.
I thought that the order of arithmetic operations specifies
left to right sequence.
You may well have thought that.ÿ You were wrong.ÿ Do you understand that >>> now?
"x *= ++f * ++f"
int x = 5;
int y = 3;
For the calculation is question is seems to make no difference to the result.
x = 5 * (4 * 5)
x = 5 * (5 * 4)
In this case no, but if the operation was - it would,
And, as pointed out there is no requirement on the ordering of even the sub-parts except determinism (we can't use a value we haven't computed
yet). This means the ++ can be interleaved.
And, because of the EXPLICIT requirement on updates to a value needing
to be ordered to avoid undefined behavior, the compiler, seeing that Undefined Behavior exist there can do ANYTHING it wants with that code.
On 5/23/2024 9:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
For that specific case the result would seem to be identical
no matter the sequence of the incrementations for int type: f.
I might not understand this fully.
On 6/22/2024 9:52 AM, David Brown wrote:
On 22/06/2024 14:40, olcott wrote:
On 6/22/2024 6:09 AM, David Brown wrote:
On 22/06/2024 06:02, olcott wrote:It would be bad for the standards to be counter-intuitive.
On 6/21/2024 10:42 PM, James Kuyper wrote:
On 6/21/24 7:06 PM, olcott wrote:
...
When we assume the *= assigns
the result of the RHS * the LHS to the LHS
"x *= ++f * ++f"
means x = x * (++f * ++f)
thus cannot have implementation defined behavior.
You are correct about that conclusion, though I don't see what your >>>>>> premise has to do with it. The expression ++f * ++f has, all by
itself,
undefined behavior,
It would seem to be naturally defined to be Left to right
++f from 2 to 3
++f from 3 to 4
3 * 4
Some programming languages define the order of evaluation for
subexpressions like this.ÿ Neither C nor C++ do (except for specific
operators, which do not include multiplication).
It doesn't really matter what you consider "natural" or not - it
matters what the standards say.
People's "intuition" varies wildly.ÿ Pretty much any definition would
be counter-intuitive to someone.ÿ That's why language standards try to
have precise definitions, rather than just saying "it all works pretty
much like you'd expect".
We realise the definition of C and C++ expression evaluation does not
match what you thought was "intuitive".ÿ That does not matter - it
would not matter even if lots of C and C++ programmers agreed with
you.ÿ What matters for these languages is what their standards /say/.
That way, we can look at clear facts written in official documents,
rather than trying to rely on what random people think about to be how
they imagine things ought to be.
You can happily feel that C would be better if evaluation order were
strictly define.ÿ Some people will agree with that, others will
disagree - but it will not make a blind bit of difference to the
actual /facts/ of the matter.
Then make the rule strict left to right unless otherwise specified.
int x = 2 + 3 * 5; // is otherwise specified by operator precedence.
On 6/22/24 10:51 PM, olcott wrote:
On 5/23/2024 9:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
For that specific case the result would seem to be identical
no matter the sequence of the incrementations for int type: f.
I might not understand this fully.
Nope, the issue is that increment isn't an atomic operation, but the
storing of the incremented result is allowed to happen at any point
prior to the end expression it is part of. (In older terms, the sequence point);
If f was a user defined type, with a user define operator++ then yes, it
is bracketed with sequencing and the two will not overlap, but not for primative types.
On 6/23/2024 6:32 AM, Richard Damon wrote:
On 6/22/24 10:51 PM, olcott wrote:
On 5/23/2024 9:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
For that specific case the result would seem to be identical
no matter the sequence of the incrementations for int type: f.
I might not understand this fully.
Nope, the issue is that increment isn't an atomic operation, but the
storing of the incremented result is allowed to happen at any point
prior to the end expression it is part of. (In older terms, the
sequence point);
If f was a user defined type, with a user define operator++ then yes,
it is bracketed with sequencing and the two will not overlap, but not
for primative types.
It is not f++, it is ++f meaning the the operation must occur before
the value is accessed.
On 6/23/24 8:59 AM, olcott wrote:
On 6/23/2024 6:32 AM, Richard Damon wrote:
On 6/22/24 10:51 PM, olcott wrote:
On 5/23/2024 9:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
For that specific case the result would seem to be identical
no matter the sequence of the incrementations for int type: f.
I might not understand this fully.
Nope, the issue is that increment isn't an atomic operation, but the
storing of the incremented result is allowed to happen at any point
prior to the end expression it is part of. (In older terms, the
sequence point);
If f was a user defined type, with a user define operator++ then yes,
it is bracketed with sequencing and the two will not overlap, but not
for primative types.
It is not f++, it is ++f meaning the the operation must occur before
the value is accessed.
But the writing back of the result does not.
The ++ and -- operators are NOT defined to be in any way "atomic".
On 6/23/2024 1:25 PM, Richard Damon wrote:
On 6/23/24 8:59 AM, olcott wrote:
On 6/23/2024 6:32 AM, Richard Damon wrote:
On 6/22/24 10:51 PM, olcott wrote:
On 5/23/2024 9:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
For that specific case the result would seem to be identical
no matter the sequence of the incrementations for int type: f.
I might not understand this fully.
Nope, the issue is that increment isn't an atomic operation, but the
storing of the incremented result is allowed to happen at any point
prior to the end expression it is part of. (In older terms, the
sequence point);
If f was a user defined type, with a user define operator++ then
yes, it is bracketed with sequencing and the two will not overlap,
but not for primative types.
It is not f++, it is ++f meaning the the operation must occur before
the value is accessed.
But the writing back of the result does not.
The ++ and -- operators are NOT defined to be in any way "atomic".
In other words it is not a direct memory increment?
On 6/23/24 3:18 PM, olcott wrote:
On 6/23/2024 1:25 PM, Richard Damon wrote:
On 6/23/24 8:59 AM, olcott wrote:
On 6/23/2024 6:32 AM, Richard Damon wrote:
On 6/22/24 10:51 PM, olcott wrote:
On 5/23/2024 9:14 AM, Bonita Montero wrote:
Is "x *= ++f * ++f" a valid statement ?
Or is there implementation defined behaviour ?
For that specific case the result would seem to be identical
no matter the sequence of the incrementations for int type: f.
I might not understand this fully.
Nope, the issue is that increment isn't an atomic operation, but
the storing of the incremented result is allowed to happen at any
point prior to the end expression it is part of. (In older terms,
the sequence point);
If f was a user defined type, with a user define operator++ then
yes, it is bracketed with sequencing and the two will not overlap,
but not for primative types.
It is not f++, it is ++f meaning the the operation must occur before
the value is accessed.
But the writing back of the result does not.
The ++ and -- operators are NOT defined to be in any way "atomic".
In other words it is not a direct memory increment?
Not required to be, since not all computers have one.
It CAN be, (and may well be on many processors) but isn't required to be.
I'd say in simple words, if you alter a variable multiple times in one statement, you get UB.
I'd say in simple words, if you alter a variable multiple times in one statement, you get UB.
I'd say in simple words, if you alter a variable multiple times in one statement, you get UB.
On 7/22/24 13:51, testuseri2p wrote:
I'd say in simple words, if you alter a variable multiple times in one
statement, you get UB.
The correct (and admittedly more complicated) statement of the relevant
rule is:
"If a side effect on a memory location (6.7.1) is unsequenced relative
to either another side effect on the same memory location or a value computation using the value of any object in the same memory location,
and they are not potentially concurrent (6.9.2), the behavior is undefined."
The biggest difference between the exact rule and what you said is that
two different updates to a variable may occur in the same statement, so
long as they are sequenced relative to each other. Sub-expressions of an expression are sequenced before evaluation of the expression itself. In general, the sub-expressions of a expression are unsequenced, but there several exceptions: ||, &&, ?:, the comma operator.
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which no declaration exists - it is still undefined behavior to write code that applies unsequence side-effects to such memory locations.
I'd say in simple words, if you alter a variable multiple times in one statement, you get UB.
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
On 7/22/24 13:51, testuseri2p wrote:
I'd say in simple words, if you alter a variable multiple times in one
statement, you get UB.
The correct (and admittedly more complicated) statement of the relevant
rule is:
"If a side effect on a memory location (6.7.1) is unsequenced relative
to either another side effect on the same memory location or a value
computation using the value of any object in the same memory location,
and they are not potentially concurrent (6.9.2), the behavior is
undefined."
The biggest difference between the exact rule and what you said is that
two different updates to a variable may occur in the same statement, so
long as they are sequenced relative to each other. Sub-expressions of an
expression are sequenced before evaluation of the expression itself. In
general, the sub-expressions of a expression are unsequenced, but there
several exceptions: ||, &&, ?:, the comma operator.
"Sub-expressions of an expression are sequenced before evaluation of the expression itself." isn't quite correct. What the C++ standard says is
that "The value computations of the operands of an operator are
sequenced before the value computation of the result of the operator."
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which no
declaration exists - it is still undefined behavior to write code that
applies unsequence side-effects to such memory locations.
Digression: I'm not even sure what "variable" means in C++. The
standard defines the term, but not in a way that really tells us what it means.
"A *variable* is introduced by the declaration of a reference other than
a non-static data member or of an object. The variable’s name, if any, denotes the reference or object."
James Kuyper <jameskuyper@alumni.caltech.edu> writes:[...]
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which
no declaration exists - it is still undefined behavior to write
code that applies unsequence side-effects to such memory locations.
Digression: I'm not even sure what "variable" means in C++. The
standard defines the term, but not in a way that really tells us
what it means.
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name,
if any, denotes the reference or object."
On 7/22/24 13:51, testuseri2p wrote:
I'd say in simple words, if you alter a variable multiple times in
one statement, you get UB.
The correct (and admittedly more complicated) statement of the
relevant rule is:
"If a side effect on a memory location (6.7.1) is unsequenced
relative to either another side effect on the same memory location
or a value computation using the value of any object in the same
memory location, and they are not potentially concurrent (6.9.2),
the behavior is undefined."
The biggest difference between the exact rule and what you said is
that two different updates to a variable may occur in the same
statement, so long as they are sequenced relative to each other. Sub-expressions of an expression are sequenced before evaluation of
the expression itself. In general, the sub-expressions of a
expression are unsequenced, but there several exceptions: ||, &&,
?:, the comma operator.
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which
no declaration exists - it is still undefined behavior to write code
that applies unsequence side-effects to such memory locations.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
James Kuyper <jameskuyper@alumni.caltech.edu> writes:[...]
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which
no declaration exists - it is still undefined behavior to write
code that applies unsequence side-effects to such memory locations.
Digression: I'm not even sure what "variable" means in C++. The
standard defines the term, but not in a way that really tells us
what it means.
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name,
if any, denotes the reference or object."
What part do you find confusing or hard to understand?
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
James Kuyper <jameskuyper@alumni.caltech.edu> writes:[...]
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which
no declaration exists - it is still undefined behavior to write
code that applies unsequence side-effects to such memory locations.
Digression: I'm not even sure what "variable" means in C++. The
standard defines the term, but not in a way that really tells us
what it means.
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name,
if any, denotes the reference or object."
What part do you find confusing or hard to understand?
The missing part that should tell us what a variable *is*.
It says that certain declarations "introduce" a variable. That's a
statement about variables, but it doesn't say what a variable is.
Given:
int n;
we know that the declaration introduces a variable. Is the object
itself a "variable"? That's the obvious meaning, and it's consistent
with what the standard says. Or is a "variable" some kind of logical
binding between an object and a name? That's also consistent with what
the standard says. Under the latter interpretation, the "variable" has
a name, and that name denotes an object, but the variable is not the
object.
Given the above declaration, is the introduced variable an object? If
so, or if not, how does your answer follow from what the standard says?
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
[...]
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which
no declaration exists - it is still undefined behavior to write
code that applies unsequence side-effects to such memory locations.
Digression: I'm not even sure what "variable" means in C++. The
standard defines the term, but not in a way that really tells us
what it means.
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name,
if any, denotes the reference or object."
What part do you find confusing or hard to understand?
The missing part that should tell us what a variable *is*.
It says that certain declarations "introduce" a variable. That's a
statement about variables, but it doesn't say what a variable is.
Given:
int n;
we know that the declaration introduces a variable. Is the object
itself a "variable"? That's the obvious meaning, and it's consistent
with what the standard says. Or is a "variable" some kind of logical
binding between an object and a name? That's also consistent with
what the standard says. Under the latter interpretation, the
"variable" has a name, and that name denotes an object, but the
variable is not the object.
Given the above declaration, is the introduced variable an object?
If so, or if not, how does your answer follow from what the standard
says?
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
[...]
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which
no declaration exists - it is still undefined behavior to write
code that applies unsequence side-effects to such memory locations.
Digression: I'm not even sure what "variable" means in C++. The
standard defines the term, but not in a way that really tells us
what it means.
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name,
if any, denotes the reference or object."
What part do you find confusing or hard to understand?
The missing part that should tell us what a variable *is*.
It says that certain declarations "introduce" a variable. That's a
statement about variables, but it doesn't say what a variable is.
Given:
int n;
we know that the declaration introduces a variable. Is the object
itself a "variable"? That's the obvious meaning, and it's consistent
with what the standard says. Or is a "variable" some kind of logical
binding between an object and a name? That's also consistent with what
the standard says. Under the latter interpretation, the "variable" has
a name, and that name denotes an object, but the variable is not the
object.
Given the above declaration, is the introduced variable an object? If
so, or if not, how does your answer follow from what the standard says?
But the following paragraph says:
A *local entity* is a variable with automatic storage duration
(6.7.5.4), a structured binding (9.6) whose corresponding variable
is such an entity, or the *this object (7.5.3).
Storage duration is an attribute of objects. If a variable can have automatic storage duration, then apparently a variable is an object.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
[...]
A minor detail is that a variable must be declared, whereas memory
locations can, for instance, be part of allocated memory for which
no declaration exists - it is still undefined behavior to write
code that applies unsequence side-effects to such memory locations.
Digression: I'm not even sure what "variable" means in C++. The
standard defines the term, but not in a way that really tells us
what it means.
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name,
if any, denotes the reference or object."
What part do you find confusing or hard to understand?
The missing part that should tell us what a variable *is*.
It says that certain declarations "introduce" a variable. That's a
statement about variables, but it doesn't say what a variable is.
Given:
int n;
we know that the declaration introduces a variable. Is the object
itself a "variable"? That's the obvious meaning, and it's consistent
with what the standard says. Or is a "variable" some kind of logical
binding between an object and a name? That's also consistent with
what the standard says. Under the latter interpretation, the
"variable" has a name, and that name denotes an object, but the
variable is not the object.
Given the above declaration, is the introduced variable an object?
If so, or if not, how does your answer follow from what the standard
says?
Even moreso than the C standard, the C++ standard needs to be read holistically. That may be a damning commentary on the quality of
writing in the C++ standard, but I think it matches the reality.
Given that, when confronted with a question like the ones you ask
about the term "variable", a natural course of action to find
answers to these questions might be to open the C++ standard in
a PDF viewer, and use the viewer's search facility to look at
places where the term in question is used. The more of those that
can be looked at, the more likely it is that one will be able to
discern answers to such questions. That's probably what I would
do if I felt I needed a better understanding of, for example, what
the term "variable" is supposed to mean.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:....
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name,
if any, denotes the reference or object."
What part do you find confusing or hard to understand?
The missing part that should tell us what a variable *is*.
It says that certain declarations "introduce" a variable. That's a
statement about variables, but it doesn't say what a variable is.
Given:
int n;
we know that the declaration introduces a variable. Is the object
itself a "variable"? That's the obvious meaning, and it's consistent
with what the standard says. Or is a "variable" some kind of logical
binding between an object and a name? That's also consistent with
what the standard says. Under the latter interpretation, the
"variable" has a name, and that name denotes an object, but the
variable is not the object.
Given the above declaration, is the introduced variable an object?
If so, or if not, how does your answer follow from what the standard
says?
Even moreso than the C standard, the C++ standard needs to be read holistically. That may be a damning commentary on the quality of
writing in the C++ standard, but I think it matches the reality.
Given that, when confronted with a question like the ones you ask
about the term "variable", a natural course of action to find
answers to these questions might be to open the C++ standard in
a PDF viewer, and use the viewer's search facility to look at
places where the term in question is used. The more of those that
can be looked at, the more likely it is that one will be able to
discern answers to such questions. That's probably what I would
do if I felt I needed a better understanding of, for example, what
the term "variable" is supposed to mean.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
James Kuyper <jameskuyper@alumni.caltech.edu> writes:[...]
A minor detail is that a variable must be declared, whereas memory >>>>>> locations can, for instance, be part of allocated memory for which >>>>>> no declaration exists - it is still undefined behavior to writeDigression: I'm not even sure what "variable" means in C++. The
code that applies unsequence side-effects to such memory locations. >>>>>
standard defines the term, but not in a way that really tells us
what it means.
"A *variable* is introduced by the declaration of a reference other
than a non-static data member or of an object. The variable's name, >>>>> if any, denotes the reference or object."
What part do you find confusing or hard to understand?
The missing part that should tell us what a variable *is*.
It says that certain declarations "introduce" a variable. That's a
statement about variables, but it doesn't say what a variable is.
Given:
int n;
we know that the declaration introduces a variable. Is the object
itself a "variable"? That's the obvious meaning, and it's consistent
with what the standard says. Or is a "variable" some kind of logical
binding between an object and a name? That's also consistent with what
the standard says. Under the latter interpretation, the "variable" has
a name, and that name denotes an object, but the variable is not the
object.
Given the above declaration, is the introduced variable an object? If
so, or if not, how does your answer follow from what the standard says?
[...]
But the following paragraph says:
A *local entity* is a variable with automatic storage duration
(6.7.5.4), a structured binding (9.6) whose corresponding variable
is such an entity, or the *this object (7.5.3).
Storage duration is an attribute of objects. If a variable can have
automatic storage duration, then apparently a variable is an object.
It seems clear that the quoted sentence is meant to be read as
A *local entity* is a variable [associated with an object that
has] automatic storage duration, [etc].
I'm not sure if C++ references also have storage durations, in which
case the word "object" in that sentence might need to be replaced with "object or reference". The key point though is that the property of
having automatic storage duration is meant to be associated with the affiliated object or reference rather than with the variable itself.
Sysop: | Tetrazocine |
---|---|
Location: | Melbourne, VIC, Australia |
Users: | 6 |
Nodes: | 8 (0 / 8) |
Uptime: | 24:09:10 |
Calls: | 51 |
Files: | 21,492 |
Messages: | 68,143 |