When shorts are longer than longs !

H

Hallvard B Furuseth

Spiros said:
If some combination of value bits was a trap representation then
those bits would no longer have the same value as the
corresponding unsigned type.

C objects of different types have different values. 1 and 1U are
different values as C objects. Different semantics. Applying the
same operation to them can give different results, e.g. ~1 vs. ~1U.

These bits (in signed and unsigned integers) do _not_ have the same
value. Look again: The paragraph above takes care not to say that, it
says they _represent_ the same value. The same mathematical value, when
considered as integers. It doesn't say that these mathematical values
can be mapped back to valid signed integer values.

That said, I do expect implementations to have INT_MAX=(power of 2)-1,
and that the standard intended to say so. (Or that it does but nobody
here has spotted it yet:) It's difficult to write Standardese and be
sure you've nailed down every case you intended. C99 is more explicit
than C89, hopefully the next one will clarify it one way or another.

Still, that doesn't mean it's safe to assume all imlementors agree.
Assume to much and someday some assumption will bite you.
 
S

Spiros Bousbouras

C objects of different types have different values. 1 and 1U are
different values as C objects. Different semantics. Applying the
same operation to them can give different results, e.g. ~1 vs. ~1U.

I was talking about mathematical values and I'm pretty sure
everyone else was talking about mathematical values so I'm not
sure how the previous paragraph is relevant to the discussion.
These bits (in signed and unsigned integers) do _not_ have the same
value. Look again: The paragraph above takes care not to say that, it
says they _represent_ the same value. The same mathematical value, when
considered as integers. It doesn't say that these mathematical values
can be mapped back to valid signed integer values.

I'm afraid I don't understand which "These bits" are, which
paragraph you're referring to or the argument you're making.
That said, I do expect implementations to have INT_MAX=(power of 2)-1,
and that the standard intended to say so. (Or that it does but nobody
here has spotted it yet:) It's difficult to write Standardese and be
sure you've nailed down every case you intended. C99 is more explicit
than C89, hopefully the next one will clarify it one way or another.

Yes, since it has generated disagreement a clarification
would be nice.
Still, that doesn't mean it's safe to assume all imlementors agree.

This last sentence seems to contradict the part where you say
"That said, I do expect implementations to have INT_MAX=(power
of 2)-1"
 
K

Keith Thompson

Richard Heathfield said:
Eric Sosman said:

As I told the OP three+ years ago, I need to complete the test
before I can give out that kind of detail.

I can, however, confirm that the program is still running, and I
confidently expect it to terminate any eternity now.

So you're expecting the test to fail?
 
S

Spiros Bousbouras

No, that's not a requirement, and I had not intended to imply that it
is one. It is a description of the bit patterns that justify
concluding that the requirement has been met; the description itself
is not part of the requirement.

Call it a description if you prefer, it still doesn't exist in
the standard.
If that were the only applicable requirement, yes. However, it's only
a meaningful requirement when you consider bit patterns where the bits
are actually set,

I would say that it's a meaningful requirement if each value bit
is allowed to take the value 1. If it does then the value it
contributes to the total value equals a power of 2.
and the standard does require the existence of such
bit patterns. The standard defines the meaning of the *_MAX and *_MIN
macros, and imposes minimum values for those which are positive, and
maximum values for those which are negative. This implies that
requirement you're referring to must hold true for all of those
values, not just 0, and for all the bits that need to be non-zero in
order to represent one or more of those values.

Ahhh but which values? Do you think for example that an int
should be able to represent all positive values from 1 to
INT_MAX or is it consistent with the standard that the only
representable positive value is INT_MAX and every other bit
pattern where the sign bit is 0 and at least one value bit is 1
may be a trap representation ? From my interpretation it follows
readily that all positive values from 1 to INT_MAX are
representable but I don't see how it follows from yours.
However, it's not
required to apply for values greater than INT_MAX, and the standard is
not as strict in it's requirements for the ranges of signed integer
types as it for the ranges of unsigned types.

I on the other hand believe that values greater than INT_MAX are
not representable because there aren't enough value bits to
represent them.

[...]
No, I'm saying that it would be redundant if your interpretation were
correct, which I deny.

Yes , that's what I thought you meant. And I was pointing out
that even if my interpretation is correct the only part which
may be redundant is "2**N - 1". Furthermore, regardless of whose
interpretation is correct, the "2**CHAR_BIT - 1" part in
footnote 40 is redundant.
It needs to be said precisely because it is not
redundant, because it implies that all possible combinations of bit
patterns must actually represent valid values, something which is not
otherwise deducible, and which is therefore not required for signed
integer types.

And as I said previously, even with my interpretation,
paragraph 1 still needs to explain how the values of individual
bits combine to give the total value. So the only question is
whether the maximum representable value (2**N - 1) needs to be
mentioned explicitly. It may be actually that even with your
interpretation we can conclude from the "pure binary
representation" part that the maximum representable value is
2**N - 1. So there's no difference in what paragraph 1 should
say regardless of whose interpretation is correct.
I'm drawing conclusions from it's failure to contain a similar
statement for signed integers.

I thought you were making the argument that if my interpretation
is correct then some bit in the standard is redundant therefore
my interpretation is less likely to be correct. And I was
replying to that that if my interpretation is correct the
part which may be redundant consists only of a few characters
(2**N - 1) and in any case a similar redundant part exists in
footnote 40 therefore the probability of my interpretation being
correct is not influenced by any such redundancies.
It doesn't need to say that; it's already been said when the concept
of trap representations were introduced. In the absence of a statement
to the contrary, the fact that trap representations are permitted to
exist implies that they can include value, sign, and padding bits.

Since a trap representation is the whole object representation
it obviously includes everything which may exist in the pattern.
But you are making the additional claim that even in the absence
of padding bits and even if the sign bit is 0 trap
representations are still possible. I would say that definitely
requires an explicit mention, if true.
No, I don't consider that there must be some hidden meaning. It seems
to me a quite open and obvious one. One clause, specifically
restricted to unsigned integer types, imposes a requirement. One
clause, specifically restricted to signed integer types, imposes no
such requirement. I don't see anything hidden about that - the
conclusion that the requirement applies only to unsigned integer types
seems quite natural to me. What would have to count as "hidden" is the
"inheritance" of this requirement by signed integer types.

There's no inheritance involved, only deduction. The hidden part
I referred to is "even in the absence....trap representations
are still possible" I mentioned above.
If you see a sign in an airport which says "Incoming passengers who
are not US citizens: use gates 1-4. You will have to pass through
Customs before you are allowed to leave the airport. Incoming
passengers who are US citizens: use gates 5-8." Would you conclude
that US citizens would have to go through Customs? That seems to me to
be implications of the "logic" you're using.

No I wouldn't conclude that US citizens would have to go through
customs but if the sign said in addition to your part, "Apart
from gates, US citizens must follow the same steps as non-US
citizens" I *would* conclude that US citizens have to go through
customs.
 
S

Spiros Bousbouras

Another interesting thing to ponder is that with a
two's complement representation, if the maximum
value for a signed type is not of the form 2**N-1
then the value -1 is not representable in that type.
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:

Eternity is forever, not just for a lifetime.

Taking this far more seriously than I should, an infinite loop doesn't
terminate after an eternity. It doesn't terminate *at all*. If
"after an eternity" were meaningful, the loop would continue to run
after an eternity.
 
J

jameskuyper

Spiros said:
Call it a description if you prefer, it still doesn't exist in
the standard.

Agreed, and I made no claim that it did. I was merely pointing out
that the bit patterns so-described happen to satisfy the requirement
that is in the standard.

....
may be a trap representation ? From my interpretation it follows
readily that all positive values from 1 to INT_MAX are
representable but I don't see how it follows from yours.

It doesn't follow from mine; I had incorrectly remembered that it was
specified as part of the definitions of INT_MIN and INT_MAX, but I was
remembering incorrectly. This doesn't mean I concede the accuracy of
your interpretation, merely that I consider it a flaw that the
standard does not explicitly state that, for signed integer types, all
values from *_MIN to *_MAX must be representable.
And as I said previously, even with my interpretation,
paragraph 1 still needs to explain how the values of individual
bits combine to give the total value. ...

If so, it fails to do so. Specifying the maximum and minimum
representable values is insufficient to determine the combination
algorithm (though the obvious one is probably the simplest).
... So the only question is
whether the maximum representable value (2**N - 1) needs to be
mentioned explicitly. It may be actually that even with your
interpretation we can conclude from the "pure binary
representation" part that the maximum representable value is
2**N - 1. So there's no difference in what paragraph 1 should
say regardless of whose interpretation is correct.

With my interpretation, the requirement for a binary representation is
met so long as every valid representation is interpreted as binary
with bits representing the specified values, regardless of which bit
patterns the implementation chooses to treat as invalid. Therefore
specifying that "objects of that type shall be capable of
representing values from 0 to 2N -1" is not redundant, and the failure
to impose a corresponding requirement on signed types is important.
I thought you were making the argument that if my interpretation
is correct then some bit in the standard is redundant therefore
my interpretation is less likely to be correct.

No, that was only a side comment; is supports my main argument, but is
not critical to it.

....
But you are making the additional claim that even in the absence
of padding bits and even if the sign bit is 0 trap
representations are still possible. I would say that definitely
requires an explicit mention, if true.

I do indeed make that claim.

Why would an explicit mention be required? The standard says nothing
to exclude sign bits and value bits from participating in the
determination of whether or not a given representation is a trap
representation. Why would having them play such a role require special
mention?

....
No I wouldn't conclude that US citizens would have to go through
customs but if the sign said in addition to your part, "Apart
from gates, US citizens must follow the same steps as non-US
citizens" I *would* conclude that US citizens have to go through
customs.

I see no clause in the standard which parallels that. I presume you
consider that this would correspond to the part about the values that
the bits have. However, that section only describes the values that
the bits represent; it does not address whether or not the bit pattern
represents a valid value. If it does not, as is allowed by the
description of trap representations, the requirement about the values
that the individual bits represent is rendered irrelevant, without
having been violated.

I'll have to modify my analogy to cover this issue. If one sign said
"All non-US citizens must go through gates 1-4, and must pay a $20
entry fee. All US citizens must go through gates 5-8." and another
sign said "All currency held by non-US citizens has the same value as
corresponding currency held by US citizens". Would you conclude that
US citizens have to pay a $20 entry fee? That's what your argument
looks like to me.
 
J

James Dow Allen

Regarding the subject line:  7-86/((m)%255+12) as the last term shaves
off one more digit:)

Kudos to you for this macro! BTW, you do actually use it, right?
The discussion seemed to imply that it is the only "proper" solution
(beyond a much messier #elif ...)

BTW, color me lazy but I wrote a trivial C program to generate all
working expressions like "7-86/((m)%255+12)" and picked the "100"
just because the round number seemed slightly more mysterious :)

James
 
S

Spiros Bousbouras

It doesn't follow from mine; I had incorrectly remembered that it was
specified as part of the definitions of INT_MIN and INT_MAX, but I was
remembering incorrectly. This doesn't mean I concede the accuracy of
your interpretation, merely that I consider it a flaw that the
standard does not explicitly state that, for signed integer types, all
values from *_MIN to *_MAX must be representable.

I can't imagine why you consider it a flaw with the standard
rather than a flaw with your interpretation.
If so, it fails to do so. Specifying the maximum and minimum
representable values is insufficient to determine the combination
algorithm (though the obvious one is probably the simplest).

The combination algorithm *is* mentioned. It says "pure binary
representation". I take this to be the same as the "pure binary
notation" mentioned in paragraph 3 of 6.2.6.1 The fact that one
place says "representation" and the other "notation" I consider
a mere oversight. Furthermore footnote 40 gives the definition of
what "pure binary notation" is. From this it follows immediately
that the range of values is from 0 to 2**N-1 and there's no
reason to mention it explicitly in paragraph 1 of 6.2.6.2
With my interpretation, the requirement for a binary
representation is met so long as every valid representation is
interpreted as binary with bits representing the specified
values, regardless of which bit patterns the implementation
chooses to treat as invalid. Therefore specifying that
"objects of that type shall be capable of representing values
from 0 to 2N -1" is not redundant, and the failure to impose a
corresponding requirement on signed types is important.

According to your interpretation what is the significance of
"pure binary representation" ? Note that footnote 40 says "A
positional representation for integers..." and it's clear to me
that it refers to the mathematical notation where there are no
trap representations.
No, that was only a side comment; is supports my main
argument, but is not critical to it.

Well ok , I was weakening then your attempt to support your main
argument :-D
I do indeed make that claim.

Why would an explicit mention be required? The standard says
nothing to exclude sign bits and value bits from participating
in the determination of whether or not a given representation
is a trap representation. Why would having them play such a
role require special mention?

For the same reason that it mentions trap representations. What
if it mentioned padding bits but said nothing about trap
representations ? By your reasoning we would still have to
accept the possibility of trap representations because the
standard wouldn't have said anything to exclude them. So why
mention them then?

Here's another example: let's say you have written a C programme
which does not use any of the date functions. Do you think that
it might behave differently if it happens to be running on
Friday the 13th ? I expect not. But why not ? After all the
standard doesn't exclude the possibility.
I see no clause in the standard which parallels that. I
presume you consider that this would correspond to the part
about the values that the bits have.
Yes.

However, that section
only describes the values that the bits represent; it does not
address whether or not the bit pattern represents a valid
value.

If it's a trap representation then the bits do not represent any
value. Don't you find it contradictory to say that the bits
represent value but the pattern does not ?
If it does not, as is allowed by the description of
trap representations, the requirement about the values that
the individual bits represent is rendered irrelevant, without
having been violated.

If it is rendered irrelevant in a context where it is relevant
then it is being violated.
I'll have to modify my analogy to cover this issue. If one
sign said "All non-US citizens must go through gates 1-4, and
must pay a $20 entry fee. All US citizens must go through
gates 5-8." and another sign said "All currency held by non-US
citizens has the same value as corresponding currency held by
US citizens". Would you conclude that US citizens have to pay
a $20 entry fee?
No.

That's what your argument looks like to me.

And your argument sounds to me as saying that if you happen to
have a 10 dollar bill and a 20 dollar bill you might not be
allowed to use them together to buy 30 dollars worth of goods.
 
J

James Kuyper

Spiros said:
I can't imagine why you consider it a flaw with the standard
rather than a flaw with your interpretation.

Because I have sufficient self-confidence (misplaced though it may be)
not to automatically assume that my interpretation must be at fault.

....
The combination algorithm *is* mentioned. It says "pure binary
representation".

That's why I said "if so"; I did not consider that the condition of that
if was actually met.
... From this it follows immediately
that the range of values is from 0 to 2**N-1 and there's no
reason to mention it explicitly in paragraph 1 of 6.2.6.2

I would agree with that conclusion, were it not for the
already-established exceptions allowed by the definition of the term
"trap representation". It is still a binary representation if every
non-trap representation is interpreted as binary. The fact that trap
representations are not interpreted at all doesn't change that.

....
According to your interpretation what is the significance of
"pure binary representation" ?

Its significance is probably exactly the same as what you believe it to
be, for any representation not identified by the implementation as a
trap representation. My interpretation differs from yours only in that I
believe that requirement for "pure binary representation" has no
significance for trap representations.

....
For the same reason that it mentions trap representations. What
if it mentioned padding bits but said nothing about trap
representations ? By your reasoning we would still have to
accept the possibility of trap representations because the
standard wouldn't have said anything to exclude them.

No, that's not a valid application of my reasoning; though this has been
argued: many people opposed adding explicit wording about trap
representations to the C99 standard because they thought it was
redundant - that it was already implicit in the C90 standard. I don't
see that argument, actually - but it was made.

My reasoning is not that no mention of trap representation is needed in
order to make them applicable. My reasoning is that a single mention of
trap representations, as is already present in the standard, is
sufficient to render them relevant in all contexts for which that
mention applies, and that there is no need to redundantly mention trap
representations in later clauses of the standard.
Here's another example: let's say you have written a C programme
which does not use any of the date functions. Do you think that
it might behave differently if it happens to be running on
Friday the 13th ? I expect not. But why not ? After all the
standard doesn't exclude the possibility.

The difference is that trap representations are in fact defined; special
handling of Friday the 13th is not. Note, however, that it's trivial to
write programs whose behavior depends upon things that the standard
leaves unspecified, and that the committee has ruled that unspecified
behavior can vary at an implementation's choice - I don't have a
citation for that ruling, unfortunately. It's up to the implementation's
whims (which, in the case case of implementation-define behavior, must
be documented) whether or not Friday the 13th has any effect on
unspecified behavior.
If it's a trap representation then the bits do not represent any
value. Don't you find it contradictory to say that the bits
represent value but the pattern does not ?

No. So I guess that defines our differences.
And your argument sounds to me as saying that if you happen to
have a 10 dollar bill and a 20 dollar bill you might not be
allowed to use them together to buy 30 dollars worth of goods.

Thank you for that answer, because it fits my argument well. If I have
one quarter, two dimes, and five pennies, it's often the case that I am
not allowed to use them together to buy 50 cents of goods (think vending
machines). That strikes me as a very good analogy for the way that the
possibility of trap representations can foul up what otherwise seems
like airtight logic.
 
H

Hallvard B Furuseth

James said:
Kudos to you for this macro! BTW, you do actually use it, right?

A few times. But when sizeof(integer type)*CHAR_BIT will do ("at least
enough bits to hold the value") I use that, since it makes the code
easier to read for others. They won't need to look up some macro to see
what the expression does.
The discussion seemed to imply that it is the only "proper" solution
(beyond a much messier #elif ...)

Except for the INT_MAX != 2**n-1 part...
BTW, color me lazy but I wrote a trivial C program to generate all
working expressions like "7-86/((m)%255+12)" and picked the "100"
just because the round number seemed slightly more mysterious :)

Ah, clearly the superior version:) Yes, I probably also just generated
likely-looking expressions, searching for ones that "happened to work".
 
H

Hallvard B Furuseth

If that were so, the standard would be in error to define -0 and -2**N
as possible trap representations, since the formula it gives does give
these bit representations values.

it is not an error, however: the statement about the values of the
individual bits is not a statement that those bit combinations are all
valid values. What it provides is a formula to map the representations
of valid values of an integer type (whatever those might be) to
mathematical integers.

Incidentally, note that -2**N _can_ be a trap representation even for
two's complement, so some postings in this thread (including mine,
sorry) have already made too wide an assumption about the valid range.
I was talking about mathematical values and I'm pretty sure
everyone else was talking about mathematical values so I'm not
sure how the previous paragraph is relevant to the discussion.

Then I can make little sense of your argument above, that "those bits
would no longer have the same value..." See below.
I'm afraid I don't understand which "These bits" are, which
paragraph you're referring to or the argument you're making.

I'm referring to the bits the quoted standard text is referring to.
A bit in a signed integer, vs the same bit in an unsigned integer.
Yes, since it has generated disagreement a clarification
would be nice.


This last sentence seems to contradict the part where you say
"That said, I do expect implementations to have INT_MAX=(power
of 2)-1"

I _expect_ to be alive and healthy next week, yet I know a traffic
accident tomorrow might prove me wrong. If so, I or someone else will
just have to deal with the disruption in my work when it happens. It's
well and good to live as if I might die tomorrow, but there are limits
how how thoroughly it's practical to do so.
 
T

Tim Rentsch

James Kuyper said:
CHAR_BIT will not give you what you want, and 8 will, on any system
which has more than 8 bits per byte, but the extra bits per byte are all
padding bits - such systems are extremely rare; they are possibly
entirely hypothetical. CHAR_BIT will give you what you want, and 8 will
not, on systems with no padding and more than 8 bits. There's a fair
number of systems out there, mostly DSPs, where CHAR_BIT is 16.
Therefore, I think you're better off using CHAR_BIT than 8.

Neither 8 nor CHAR_BIT must produce an answer that is even just
conservatively correct. It's better to calculate based on maximum
value, which is exact and guaranteed to work for unsigned types, and
also pretty good for signed types (can be almost always correct,
always conservatively correct, with "implemention-defined signal"
being the only potential reliability issue).
 
T

Tim Rentsch

James Dow Allen said:
No one has, as yet in this thread, presented a specific system where
char_bit != 8, nor where integers have padding BUT an unchallenged
inference from Twirlip's comments suggest that this (hypothetical?)
machine has 9-bit chars and 32-bit integers. *Then* 8*sizeof would
work but char_bit*sizeof *not* work.

Another reason to suspect this is the correct approach is that
GMP uses 8, not char_bit. GMP is a very thoroughly tested and
ported piece of code.

Finally, if ints DO have 36 bits but code assumes 32 bits, the
code (if coded with care) will still work, but the converse
obviously doesn't apply.

The *real* solution is for the "standard header(s)" to contain
a BITS_PER_INT define and my question remains: Why don't they?
(Committee oversight is not an adequate answer; if the standard
needs to evolve, let it evolve.)

It's easy to calculate the exact value for (int) based
on INT_MAX.
 
T

Tim Rentsch

James Dow Allen said:
BTW, does the standard actually require that INT_MAX, etc.
be of the form (1<<b)-1 ? I don't know why they wouldn't have
that form, but I didn't know of padding bits either.

It's clear that the Standard expects that all value bits
of a signed integer type fully participate in forming
the value, so INT_MAX etc all will be of the form 2**N - 1.
It doesn't express this expectation very well, but if you
look in the Rationale and in 6.7.7 p 6 (which mentions the
range of some example bit-fields), I think you'll agree
that this condition is expected to hold. For purposes
of comp.lang.c, IMO the only reasonable answer is Yes.
 
T

Tim Rentsch

James Kuyper said:
James Dow Allen wrote:
...

I've heard the claim made that it does. The truth of that claim depends
upon how you interpret 6.2.6.2p2:

| If the sign bit is one, the value shall be
| modified in one of the following ways:
| — the corresponding value with sign bit 0 is negated (sign and
| magnitude);
| — the sign bit has the value -(2N) (two’s complement);
| — the sign bit has the value -(2N - 1) (ones’ complement).
| Which of these applies is implementation-defined, as is whether the
| value with sign bit 1 and all value bits zero (for the first two), or
| with sign bit and all value bits 1 (for ones’ complement), is a trap
| representation or a normal value.

Some people read this as giving permission for a maximum of one trap
representation that depends upon the value bits; all other trap
representations, if any, must be identified as such by looking at value
bits.

I look at that same clause, and see one specific example given where the
fact that a bit pattern is a trap reepresentation depends upon the value
bits, a case that is singled out because, in two of the permitted
interpretations for a sign bit, it is the only redundant bit pattern. I
don't see anything here prohibiting the existence of other trap
representations that depend upon value bits.

For example, I don't see any contradiction with any clause of the
standard if an implementation provides a 20-bit int with INT_MAX ==
999999, INT_MIN == -1000000, defining every bit pattern that would
otherwise represent values greater than 999999 or smaller than -1000000
to be a trap representation. Other people disagree.

If you read the comments in the Rationale document, and
also consider the discussion (even though non-normative)
in 6.7.7 p 6, you may reach a different conclusion.
This issue is more suited for a discussion in comp.std.c
than comp.lang.c; pragmatically, the answer is clear.
 
T

Tim Rentsch

James Kuyper said:
Those bits have the same value as in the unsigned type, for every bit
pattern which is not a trap representation. The existence of even a
single such bit pattern is sufficient to meet that requirement.


Your argument above implies that the statement describing the
representable range of values is redundant. The committee apparently
thought it was necessary, anyway, which suggests (but admittedly does
not prove) that they did not consider it redundant.

It isn't redundant; it establishes that the overall value
is the sum of the individual value bits. If this relationship
weren't established, the overall value might be, eg, the
maximum of the individual value bits.
If it were meant to apply to signed integer types, why does that wording
occur in a clause explicitly restricted in it's application to unsigned
integer types?

Because that clause is discussing only unsigned types. The analogous
condition for signed types is brought out in a clause that discusses
signed types. Obvious, no?
Why is there no comparable wording in the clause for
signed integer types - the standard is not shy about repeating itself in
other, comparable situations.

On the contrary, in my experience the Standard very rarely
(normatively) expresses the same implication more than once.
I think the only conclusion to be drawn here is that the
people who wrote the Standard thought it was too obvious to
merit a footnote.
Better yet, it could have been written
exactly once (with suitable modifications), in a clause that explicitly
stated that it applied to all integer types, signed and unsigned. Why
wasn't it?

Because the writers are human? An identical statement doesn't hold
for signed types, because they have negative values. It's not as
easy as it first appears; if you actually try writing it I think
you'll find the changes are more difficult and more extensive than
you first expect.


By the way, the possessive form of "it" should be written
with no apostrophe. "It's" always means "it is" (or perhaps
"it was").
 
L

luserXtrog

Tim Rentsch said:



Never "it was", but it can mean "it has". For example, "the value of
an object should not be accessed once it's gone out of scope".

Only today I saw a solicitation that read: "Our job is keeping
your customer's safe." And it wasn't a bank.

Indeed the error is among those whose ubiquity triggers
an extreme ambivalence concerning whether to correct it
or let it lie.

My new pet peeve is misuse of jealousy and envy.
The biggest would have to be effect and affect.
My own mother can't keep these straight.
 
T

Tim Rentsch

Richard Heathfield said:
Tim Rentsch said:



Never "it was", but it can mean "it has". For example, "the value of
an object should not be accessed once it's gone out of scope".

Ahh, yes, that seems correct.
 

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,787
Messages
2,569,630
Members
45,338
Latest member
41Pearline46

Latest Threads

Top