On 10/25/21 10:19 AM,
Racing...@watershipdown.co.uk wrote:
> On Mon, 25 Oct 2021 09:47:50 -0000 (UTC)
> Juha Nieminen <nos...@thanks.invalid> wrote:
>>
Racing...@watershipdown.co.uk wrote:
>>> Consts in C are pointless because it doesn't have references and its rather
>>> difficult to "accidentaly" dereference a pointer to update the value its
>>> pointing to.
>>
>> Actually it isn't. Very old-style C code, mostly prior to the C89 standard,
>> but you can see even modern examples sometimes (for some old-school C coders
>> habits die hard), often used non-const pointers to char as "strings".
>
> And? How do you accidentaly write *str or str[0] for example?
It's not the *str that's accidental, its the call to a function that
contains *str, with an argument that points to a string that shouldn't
be written to. That is in fact a fairly easy mistake to made, and when
people didn't use "const" properly, it's actually a fairly common one.
...
>> In fact, I think even the K&R famous book as examples with non-const char*'s
>> being initialized to point to string literals.
>
> The concept of const didn't exist in K&R C so what would be your alternative?
There was no alternative, which is why that was the case. After "const"
was added to the language, K&R 2nd edition was updated accordingly.
...
>> call it with a pointer that's pointing to a string literal. If said
>> function does modify the "string" it's getting as parameter, that's UB.
>
> No idea what UB means, but what'll happen is it'll crash immediately so you'll
> soon find out.
UB means "Undefined Behavior", a technical term from the C standard
which does NOT mean "behavior for which there is no definition". It
means "behavior, upon use of a nonportable or erroneous program
construct or of erroneous data, for which this document imposes no
requirements" (3.4.3). Note that "this document" refers to the C
standard; other documents (such as compiler documentation or ABI
standards) might define the behavior, without changing the fact that is
qualifies as "undefined behavior" as far as the C standard is concerned.
A lot of people have trouble understanding how breath-takingly wide the
scope of "imposes no requirements" is. The standard tries to make that
clear with the following examples "Possible undefined behavior ranges
from ignoring the situation completely with unpredictable results, to
behaving during translation or program execution in a documented manner
characteristic of the environment (with or without the issuance of a
diagnostic message), to terminating a translation or execution (with the
issuance of a diagnostic message)."
Note, in particular, that the most insidious form of undefined behavior
is that your program can behave exactly the way you incorrectly thought
it was required to behave. The reason that's dangerous is that it leaves
you with no warning that the behavior might change when you recompile
with a different compiler, or with different compiler options, or even
with the same compiler options, or even if you simply run the program a
second time, even if you give it the same inputs as the previous time.
That's how comprehensive the phrase "no requirements" is - the undefined
behavior is NOT required to be the same each time you execute the
offending program.
Getting back to your comment - it's not required to crash immediately -
that would constitute a requirement. And it's actually possible, as a
result of optimizations performed by the compiler, that it might
actually do something quite different. In particular, one possibility is
the attempt to write to the object might become a NOp (as indicated by
the phrase "ignoring the situation completely").