Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #150634 > unrolled thread

"How one word broke C"

Started byLynn McGuire <lynnmcguire5@gmail.com>
First post2020-03-17 14:29 -0500
Last post2020-03-24 19:41 -0400
Articles 20 on this page of 43 — 17 participants

Back to article view | Back to comp.lang.c


Contents

  "How one word broke C" Lynn McGuire <lynnmcguire5@gmail.com> - 2020-03-17 14:29 -0500
    Re: "How one word broke C" Real Troll <Real.Troll@Trolls.com> - 2020-03-17 15:40 -0400
      Re: "How one word broke C" John Bode <jfbode1029@gmail.com> - 2020-03-19 11:57 -0700
        Re: "How one word broke C" James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-03-19 18:20 -0400
    Re: "How one word broke C" Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-03-17 13:39 -0700
      Re: "How one word broke C" Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-03-17 21:55 +0000
    Re: "How one word broke C" felix@palmen-it.de (Felix Palmen) - 2020-03-17 23:02 +0100
      Re: "How one word broke C" Richard Damon <Richard@Damon-Family.org> - 2020-03-17 21:57 -0400
        Re: "How one word broke C" Dan Purgert <dan@djph.net> - 2020-03-18 11:02 +0000
          Re: "How one word broke C" Richard Damon <Richard@Damon-Family.org> - 2020-03-18 08:58 -0400
            Re: "How one word broke C" Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-03-18 06:04 -0700
              Re: "How one word broke C" Richard Damon <Richard@Damon-Family.org> - 2020-03-18 09:53 -0400
            Re: "How one word broke C" felix@palmen-it.de (Felix Palmen) - 2020-03-18 14:46 +0100
              Re: "How one word broke C" Richard Damon <Richard@Damon-Family.org> - 2020-03-19 08:55 -0400
        Re: "How one word broke C" Philipp Klaus Krause <pkk@spth.de> - 2020-03-18 18:21 +0100
          Re: "How one word broke C" already5chosen@yahoo.com - 2020-03-18 12:11 -0700
            Re: "How one word broke C" Philipp Klaus Krause <pkk@spth.de> - 2020-03-18 21:06 +0100
              Re: "How one word broke C" Richard Damon <Richard@Damon-Family.org> - 2020-03-18 22:43 -0400
                Re: "How one word broke C" Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-03-27 07:18 -0700
          Re: "How one word broke C" Dan Purgert <dan@djph.net> - 2020-03-19 01:40 +0000
        Re: "How one word broke C" Eli the Bearded <*@eli.users.panix.com> - 2020-03-18 19:12 +0000
          Re: "How one word broke C" Philipp Klaus Krause <pkk@spth.de> - 2020-03-18 21:09 +0100
      Re: "How one word broke C" David Brown <david.brown@hesbynett.no> - 2020-03-18 21:35 +0100
        Re: "How one word broke C" felix@palmen-it.de (Felix Palmen) - 2020-03-18 23:27 +0100
          Re: "How one word broke C" Richard Damon <Richard@Damon-Family.org> - 2020-03-19 08:57 -0400
            Re: "How one word broke C" felix@palmen-it.de (Felix Palmen) - 2020-03-19 15:00 +0100
          Re: "How one word broke C" David Brown <david.brown@hesbynett.no> - 2020-03-19 15:02 +0100
            Re: "How one word broke C" felix@palmen-it.de (Felix Palmen) - 2020-03-19 15:10 +0100
              Re: "How one word broke C" gazelle@shell.xmission.com (Kenny McCormack) - 2020-03-19 14:34 +0000
                Re: "How one word broke C" Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-03-19 07:44 -0700
                  Re: "How one word broke C" Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-03-19 14:57 +0000
                  Re: "How one word broke C" felix@palmen-it.de (Felix Palmen) - 2020-03-19 15:58 +0100
                    Re: "How one word broke C" David Brown <david.brown@hesbynett.no> - 2020-03-19 16:26 +0100
                Re: "How one word broke C" David Brown <david.brown@hesbynett.no> - 2020-03-19 16:08 +0100
                  Troll, gadfly, whatever... (Was: "How one word broke C") gazelle@shell.xmission.com (Kenny McCormack) - 2020-03-21 11:08 +0000
                    Re: Troll, gadfly, whatever... (Was: "How one word broke C") Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-03-21 04:50 -0700
              Re: "How one word broke C" David Brown <david.brown@hesbynett.no> - 2020-03-19 16:04 +0100
                Re: "How one word broke C" felix@palmen-it.de (Felix Palmen) - 2020-03-19 16:16 +0100
                  Re: "How one word broke C" Richard Damon <Richard@Damon-Family.org> - 2020-03-19 23:36 -0400
            Re: "How one word broke C" James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-03-19 18:13 -0400
    Re: "How one word broke C" Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2020-03-17 19:43 -0600
      Re: "How one word broke C" John Bode <jfbode1029@gmail.com> - 2020-03-24 16:07 -0700
    Re: "How one word broke C" James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-03-24 19:41 -0400

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#150666

FromEli the Bearded <*@eli.users.panix.com>
Date2020-03-18 19:12 +0000
Message-ID<eli$2003181512@qaz.wtf>
In reply to#150640
In comp.lang.c, Richard Damon  <Richard@Damon-Family.org> wrote:
> One thing to remember also is that machines were much more varied back
> then in the early stages of the language, with a number of very strange
> machines, so some things that today seem easy enough to make
> implementation defined weren't so easy to define. While machines have
> gotten more standardized, optimizations that some people think as
> important have been developed on the assumption that code doesn't do any
> of they operations with undefined behavior,

Looking at the platforms supported by zlib or sqlite:

https://www.sqlite.org/mostdeployed.html

should give some idea of the range of machines C is still being used on.
Sure 36- and 28-bit machines, and other exotics, are a thing of the
past, but the processer in a Fitbit device the size of one of my finger
bones isn't anything like as standard as Raspberry Pi. (I don't know if
that Fitbit is using zlib or sqlite, but I know they are programming
them with C.)

I don't know, but I expect that the firmware in things like size-of-a-
fingernail microSD cards are also written in C.

Elijah
------
then there are all those arduinos out there

[toc] | [prev] | [next] | [standalone]


#150668

FromPhilipp Klaus Krause <pkk@spth.de>
Date2020-03-18 21:09 +0100
Message-ID<r4tv5h$14q$2@solani.org>
In reply to#150666
Also have a look at the architectures upported by the Small Device C
compiler (SDCC). Yes, even the pdk13 backend has 8-bit bytes in RAM. But
e.g. program memory is 13-bit wide words for pdk13. The stm8 backend
(when using the --model-large option) is an example where pointers to
objects have a size (16 bit) different from pointers to functions (24 bit).

[toc] | [prev] | [next] | [standalone]


#150670

FromDavid Brown <david.brown@hesbynett.no>
Date2020-03-18 21:35 +0100
Message-ID<r4u0m5$721$1@dont-email.me>
In reply to#150638
On 17/03/2020 23:02, Felix Palmen wrote:
> * Lynn McGuire <lynnmcguire5@gmail.com>:
>> "How one word broke C"
>>     https://news.quelsolaar.com/2020/03/16/how-one-word-broke-c/
>>
>> " [...]                                  In my opinion Undefined
>> behavior is not inherently bad.  C is meant to be implementable on lots
>> of different platforms and, to require all of them to behave in the
>> exact same way would be impractical, it would limit hardware development
>> and make C less future proof. [...]                               "
> 
> That already misses the point. Most newer languages are “fully defined”
> without restricting the platforms they can be implemented on
> significantly. Practical portability might be a reason for
> “implementation defined” bits in the standard, like the actual sizes of
> some types, the representation of negative numbers, etc... They often
> allow an implementation to map efficiently to instructions of the target
> platform, but require that the behavior is reliable and documented.
> 
> But for *undefined* behavior, the reason is more likely that diagnosing
> a program triggering it would only be possible at runtime. C is designed
> with as little as possible overhead in mind, so a large runtime
> environment doing all sorts of checks isn't necessary. The cost for this
> kind of efficiency is UB.
> 

You are imagining that undefined behaviour is a "cost" - it is not.  It 
is a bonus - a benefit that C and C++ programmers get, that programmers 
of other languages often do not have.

The fact that things like out-of-bounds array access, signed integer 
overflow, reading uninitialised local variables, etc., is undefined 
behaviour is a /good/ thing.  It makes it easier to write good, correct 
programs.  This is because doing any of these things, in any language, 
is (almost invariably) a mistake.  Languages which define a behaviour 
here are just sweeping the problem under a rug.  Some might give you a 
run-time error when these happen - then you have a chance to find them, 
but only if you are lucky during testing.  With C and C++, many of these 
can be spotted by the compiler (or more advanced static analysis tools) 
so you are warned as early as possible.

Even worse are languages that define the behaviour of signed integer 
overflow as wrapping - that hides the errors in the code as much as 
possible.  A compiler for such a language can't give you any help in 
finding the bugs - a C or C++ compiler has a chance of spotting them at 
compile time, and is always free to add run-time checks to aid your 
debugging.

Learn to /love/ undefined behaviour in C and C++ - it really is your 
friend, once you understand it.

[toc] | [prev] | [next] | [standalone]


#150676

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-03-18 23:27 +0100
Message-ID<brjakg-hlj2.ln1@mail.home.palmen-it.de>
In reply to#150670
* David Brown <david.brown@hesbynett.no>:
> You are imagining that undefined behaviour is a "cost" - it is not.  It 
> is a bonus - a benefit that C and C++ programmers get, that programmers 
> of other languages often do not have.

No, it is a cost paid for a bonus.

> The fact that things like out-of-bounds array access, signed integer 
> overflow, reading uninitialised local variables, etc., is undefined 
> behaviour is a /good/ thing.  It makes it easier to write good, correct 
> programs.

That's really wishful thinking. Don't get me wrong, I like C the way it
is and I'm quite happy with the fact that it has UB. But if anything, it
makes it /harder/ to write correct programs, because:

> This is because doing any of these things, in any language, 
> is (almost invariably) a mistake.  Languages which define a behaviour 
> here are just sweeping the problem under a rug.

They define the behavior to reliably indicate an error (fail fast).
That's quite the opposite of sweeping. An incorrect C program OTOH could
just work as you expect (and it often does exactly that).

If there's anything good about UB with respect to writing correct
programs, it's that it teaches you to be extra careful.

> Some might give you a 
> run-time error when these happen - then you have a chance to find them, 
> but only if you are lucky during testing.

You shouldn't have to "be lucky" if your test cases are written
properly. But with C, even full test coverage is no guarantee, thanks to
UB.

> With C and C++, many of these 
> can be spotted by the compiler (or more advanced static analysis tools) 
> so you are warned as early as possible.

For varying definitions of "many". I assume you are familiar with the
halting problem? A good compiler or analysis tool is great, of course
everyone prefers getting errors at build time. But this applies to any
language, and it's always impossible to fully analyze a program without
running it, theoretical proof exists. So, do you prefer those errors
that can't be found at build time to potentially stay hidden or to
reliably fail at runtime?

> Even worse are languages that define the behaviour of signed integer 
> overflow as wrapping - that hides the errors in the code as much as 
> possible.

That would be a pretty stupid design decision (which language does
that?), but comes close to what some C implementations (legally, because
of UB) do.

-- 
 Dipl.-Inform. Felix Palmen  <felix@palmen-it.de>   ,.//..........
 {web}  http://palmen-it.de  {jabber} [see email]   ,//palmen-it.de
 {pgp public key}     http://palmen-it.de/pub.txt   //   """""""""""
 {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A

[toc] | [prev] | [next] | [standalone]


#150685

FromRichard Damon <Richard@Damon-Family.org>
Date2020-03-19 08:57 -0400
Message-ID<V_JcG.266962$%Y7.160486@fx04.iad>
In reply to#150676
On 3/18/20 6:27 PM, Felix Palmen wrote:
> * David Brown <david.brown@hesbynett.no>:
>> You are imagining that undefined behaviour is a "cost" - it is not.  It 
>> is a bonus - a benefit that C and C++ programmers get, that programmers 
>> of other languages often do not have.
> 
> No, it is a cost paid for a bonus.
> 
>> The fact that things like out-of-bounds array access, signed integer 
>> overflow, reading uninitialised local variables, etc., is undefined 
>> behaviour is a /good/ thing.  It makes it easier to write good, correct 
>> programs.
> 
> That's really wishful thinking. Don't get me wrong, I like C the way it
> is and I'm quite happy with the fact that it has UB. But if anything, it
> makes it /harder/ to write correct programs, because:
> 
>> This is because doing any of these things, in any language, 
>> is (almost invariably) a mistake.  Languages which define a behaviour 
>> here are just sweeping the problem under a rug.
> 
> They define the behavior to reliably indicate an error (fail fast).
> That's quite the opposite of sweeping. An incorrect C program OTOH could
> just work as you expect (and it often does exactly that).
> 
> If there's anything good about UB with respect to writing correct
> programs, it's that it teaches you to be extra careful.
> 
>> Some might give you a 
>> run-time error when these happen - then you have a chance to find them, 
>> but only if you are lucky during testing.
> 
> You shouldn't have to "be lucky" if your test cases are written
> properly. But with C, even full test coverage is no guarantee, thanks to
> UB.
> 
>> With C and C++, many of these 
>> can be spotted by the compiler (or more advanced static analysis tools) 
>> so you are warned as early as possible.
> 
> For varying definitions of "many". I assume you are familiar with the
> halting problem? A good compiler or analysis tool is great, of course
> everyone prefers getting errors at build time. But this applies to any
> language, and it's always impossible to fully analyze a program without
> running it, theoretical proof exists. So, do you prefer those errors
> that can't be found at build time to potentially stay hidden or to
> reliably fail at runtime?
> 
>> Even worse are languages that define the behaviour of signed integer 
>> overflow as wrapping - that hides the errors in the code as much as 
>> possible.
> 
> That would be a pretty stupid design decision (which language does
> that?), but comes close to what some C implementations (legally, because
> of UB) do.
> 

What UB does is make it possible to write debugging implementation that
do check for many of these problems and generate traps for them, while
at the same time allow for release implementations that don't, and run
faster.

[toc] | [prev] | [next] | [standalone]


#150687

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-03-19 15:00 +0100
Message-ID<4gackg-icl.ln1@mail.home.palmen-it.de>
In reply to#150685
* Richard Damon <Richard@damon-family.org>:
> What UB does is make it possible to write debugging implementation that
> do check for many of these problems and generate traps for them, while
> at the same time allow for release implementations that don't, and run
> faster.

Yes, for *many*. But many others will be missed no matter what. E.g.
many forms of invalid aliasing.

UB isn't a good thing per se. It's a necessity if you want a different
good thing: efficient code, efficient compilation and the potential for
aggressive optimization. If you use C, you accept UB because you want
the other goodies.

-- 
 Dipl.-Inform. Felix Palmen  <felix@palmen-it.de>   ,.//..........
 {web}  http://palmen-it.de  {jabber} [see email]   ,//palmen-it.de
 {pgp public key}     http://palmen-it.de/pub.txt   //   """""""""""
 {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A

[toc] | [prev] | [next] | [standalone]


#150688

FromDavid Brown <david.brown@hesbynett.no>
Date2020-03-19 15:02 +0100
Message-ID<r4vu10$dt$1@dont-email.me>
In reply to#150676
On 18/03/2020 23:27, Felix Palmen wrote:
> * David Brown <david.brown@hesbynett.no>:
>> You are imagining that undefined behaviour is a "cost" - it is not.  It
>> is a bonus - a benefit that C and C++ programmers get, that programmers
>> of other languages often do not have.
> 
> No, it is a cost paid for a bonus.

(I'm concerned here with undefined behaviour at run-time, rather than 
things like declaring a function in one place and defining it in another 
place with different parameters.  Good code structure and compiler flags 
eliminate that kind of thing for the most part.)


There is no cost.

Look, your aim is to write bug-free code, agreed?

So the two concerns are how does UB affect correct code once it is 
written, and how does UB affect finding or avoiding the bugs in order to 
get correct code?

First, consider correct code.  This code does not let signed integer 
operations overflow, since any answer would be wrong.  It does not 
access arrays out of bounds, since that could not possibly be correct. 
It does not dereference null pointers, or free pointers twice, or use 
any function or operator in the language outside of the specifications 
(given by the standards and the implementation).  What does it matter if 
dereferencing a null pointer launches nasal demons?  Nothing at all, 
since your code never dereferences a null pointer.  UB is /zero/ cost 
for correct code.  (And because it allows more optimisations, it is a 
positive benefit.)

Then consider finding bugs.  Undefined behaviour is always a bug - and 
thus compilers and analysis tools can complain about them and give 
warnings about them.  Of course no tool can find every fault, but they 
are getting steadily better at finding more.  And you can have run-time 
tools such as specialised memory allocators and "sanitizers" that add 
run-time checks of various types in order to catch a lot of undefined 
behaviour.

If the behaviour were defined, the compiler (and other static and 
run-time diagnostic tools) would have to follow that definition - and it 
cannot distinguish between coding errors and intentional code.  If your 
calculations overflow, but the language says that adding big positive 
numbers should give a negative number, that's what you get - and your 
tools have no option to add a run-time check, because the ridiculous 
behaviour is "correct" according to the language.



There is one other situation in the middle here - when you think your 
code is correct, and you release it, but there is accidental undefined 
behaviour left.  What happens if you hit it?  Nasal demons, in theory. 
In practice, it might lead to a crash (typical for pointer problems), it 
might hit a "undefined behaviour" or breakpoint opcode (contrary to 
conspiracy theories, compilers try to be helpful when dealing with UB), 
or it might carry on with odd results that cause trouble in different 
places.  What would happen in a programming language with defined 
handling of these same problems?  It might throw an error or exception, 
leading to a crash or halt of the program (remember we are talking about 
problems that you haven't foreseen), or it might carry on with odd 
behaviour, leading to trouble in different places later on.


The UB in C and C++ is either a benefit, or no worse than languages 
(like Java) that give defined behaviour to these things.

If you can't handle this, or don't want to handle it, you need to use a 
language which avoids the kind of situations that are UB in C - not one 
that glosses over them.  That means a language that has all the run-time 
tests in place all the time, and which does not allow free pointers and 
other "dangerous" concepts.  You need a language like Python where 
integers grow, rather than overflow, and there are no pointers.

> 
>> The fact that things like out-of-bounds array access, signed integer
>> overflow, reading uninitialised local variables, etc., is undefined
>> behaviour is a /good/ thing.  It makes it easier to write good, correct
>> programs.
> 
> That's really wishful thinking. Don't get me wrong, I like C the way it
> is and I'm quite happy with the fact that it has UB. But if anything, it
> makes it /harder/ to write correct programs, because:
> 
>> This is because doing any of these things, in any language,
>> is (almost invariably) a mistake.  Languages which define a behaviour
>> here are just sweeping the problem under a rug.
> 
> They define the behavior to reliably indicate an error (fail fast).
> That's quite the opposite of sweeping. An incorrect C program OTOH could
> just work as you expect (and it often does exactly that).

Often they don't give an error - they just continue regardless of the 
nonsense in progress.  A prime example is Java's wrapping signed 
integers.  And when you are dealing with unexpected errors, the result 
is generally a crash whether it is from the language run-time or from 
the OS.  If you accidentally dereference a null pointer, it makes very 
little difference to the user whether they see a message saying your Ada 
program has thrown an uncaught exception, or your C program has caused a 
segmentation fault.

All you can be sure about is when the behaviour is defined by the 
language, your chances of finding it with static analysis are nil - with 
C, you might have /some/ chance at least.

> 
> If there's anything good about UB with respect to writing correct
> programs, it's that it teaches you to be extra careful.

That's another bonus.

> 
>> Some might give you a
>> run-time error when these happen - then you have a chance to find them,
>> but only if you are lucky during testing.
> 
> You shouldn't have to "be lucky" if your test cases are written
> properly. But with C, even full test coverage is no guarantee, thanks to
> UB.

If you can actually get full test coverage, then UB is not a hinder. 
Usually, however, you can't - and tests are a matter of luck.  Testing 
can prove the presence of bugs, but not the absence - anyone who tells 
you their code is "fully tested" is almost certainly exaggerating or 
mistaken.  (I am not dismissing testing - it is vital in code development.)

> 
>> With C and C++, many of these
>> can be spotted by the compiler (or more advanced static analysis tools)
>> so you are warned as early as possible.
> 
> For varying definitions of "many". I assume you are familiar with the
> halting problem? A good compiler or analysis tool is great, of course
> everyone prefers getting errors at build time. But this applies to any
> language, and it's always impossible to fully analyze a program without
> running it, theoretical proof exists. So, do you prefer those errors
> that can't be found at build time to potentially stay hidden or to
> reliably fail at runtime?

"Reliable failure" is an oxymoron.

Yes of course static analysis is always limited - even if tools are 
getting steadily better.  But I prefer "finds some errors during 
compilation" over "ignores all errors until runtime".

I prefer code to be designed in a way that avoids the risk of the 
failures.  And I think it is a good think to put in appropriate manual 
checks where you are not sure (asserts are popular in C - and much more 
flexible than any language-based runtime checks), and to test code with 
sanitizers or debug libraries.

I don't think it would do much harm for people to release some C code 
with certain kinds of run-time checks still enabled (with sanitizers). 
With UB, you have that option.

I also don't think C is an appropriate choice of language for many 
people, and for a lot of code that is currently written in it.  Trying 
to reduce UB in C would be the wrong way to reduce errors - the aim 
should be in getting people who write code with UB to use safer, simpler 
(but less efficient) languages instead.

> 
>> Even worse are languages that define the behaviour of signed integer
>> overflow as wrapping - that hides the errors in the code as much as
>> possible.
> 
> That would be a pretty stupid design decision (which language does
> that?), but comes close to what some C implementations (legally, because
> of UB) do.
> 

Java has wrapped signed integer arithmetic, as does unchecked C#. 
(Detection and trapping would cripple efficiency of arithmetic code.)

Wrapping behaviour is also almost invariably the suggestion people give 
when they say they want defined behaviour for integer overflow in C.  It 
is one of the least inefficient choices, but also the least helpful.

[toc] | [prev] | [next] | [standalone]


#150689

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-03-19 15:10 +0100
Message-ID<s2bckg-ngl.ln1@mail.home.palmen-it.de>
In reply to#150688
* David Brown <david.brown@hesbynett.no>:
> If the behaviour were defined, the compiler (and other static and 
> run-time diagnostic tools) would have to follow that definition - and it 
> cannot distinguish between coding errors and intentional code.

You still don't see the fundamental flaw in this assumption. So stating
it directly: Fully-defined *includes* the definition of error behavior.
*Of course* the compiler and/or runtime environment can detect errors,
because they are defined as errors.

-- 
 Dipl.-Inform. Felix Palmen  <felix@palmen-it.de>   ,.//..........
 {web}  http://palmen-it.de  {jabber} [see email]   ,//palmen-it.de
 {pgp public key}     http://palmen-it.de/pub.txt   //   """""""""""
 {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A

[toc] | [prev] | [next] | [standalone]


#150690

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2020-03-19 14:34 +0000
Message-ID<r4vvsq$mdt$1@news.xmission.com>
In reply to#150689
In article <s2bckg-ngl.ln1@mail.home.palmen-it.de>,
Felix Palmen <felix@palmen-it.de> wrote:
>* David Brown <david.brown@hesbynett.no>:
>> If the behaviour were defined, the compiler (and other static and 
>> run-time diagnostic tools) would have to follow that definition - and it 
>> cannot distinguish between coding errors and intentional code.
>
>You still don't see the fundamental flaw in this assumption. So stating
>it directly: Fully-defined *includes* the definition of error behavior.
>*Of course* the compiler and/or runtime environment can detect errors,
>because they are defined as errors.

From what I can tell, David Brown majored in marketing as an undergrad,
then went to Business School and probably has an MBA.  He probably took one
or two computer course along the way.

Marketing (and B School) are all about making silk purses out of sow's ears.

That is what he has done (or at least attempted to do) in this thread.
Sell us sh*t as a feature.

There's good money in it.  I don't blame him for his efforts.

-- 
The randomly chosen signature file that would have appeared here is more than 4
lines long.  As such, it violates one or more Usenet RFCs.  In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
	http://user.xmission.com/~gazelle/Sigs/RepInsults

[toc] | [prev] | [next] | [standalone]


#150691

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-03-19 07:44 -0700
Message-ID<27679fb3-7a93-499f-b135-41b7886e3636@googlegroups.com>
In reply to#150690
On Thursday, 19 March 2020 14:34:11 UTC, Kenny McCormack  wrote:
> In article <s2bckg-ngl.ln1@mail.home.palmen-it.de>,
> Felix Palmen <felix@palmen-it.de> wrote:
> >* David Brown <david.brown@hesbynett.no>:
> >> If the behaviour were defined, the compiler (and other static and 
> >> run-time diagnostic tools) would have to follow that definition - and it 
> >> cannot distinguish between coding errors and intentional code.
> >
> >You still don't see the fundamental flaw in this assumption. So stating
> >it directly: Fully-defined *includes* the definition of error behavior.
> >*Of course* the compiler and/or runtime environment can detect errors,
> >because they are defined as errors.
> 
> From what I can tell, David Brown majored in marketing as an undergrad,
> then went to Business School and probably has an MBA.  He probably took one
> or two computer course along the way.
> 
> Marketing (and B School) are all about making silk purses out of sow's ears.
> 
> That is what he has done (or at least attempted to do) in this thread.
> Sell us sh*t as a feature.
> 
> There's good money in it.  I don't blame him for his efforts.
> 
It is, however, better to say that the results of

int array10];
array[10] = 42;

are "undefined", rather than that a 42 must be written to the position
one past the array. That means that a good compiler can trap.

[toc] | [prev] | [next] | [standalone]


#150692

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2020-03-19 14:57 +0000
Message-ID<slrnr7722d.1r7q.grahn+nntp@frailea.sa.invalid>
In reply to#150691
On Thu, 2020-03-19, Malcolm McLean wrote:
> On Thursday, 19 March 2020 14:34:11 UTC, Kenny McCormack  wrote:
>> In article <s2bckg-ngl.ln1@mail.home.palmen-it.de>,
>> Felix Palmen <felix@palmen-it.de> wrote:
>> >* David Brown <david.brown@hesbynett.no>:
>> >> If the behaviour were defined, the compiler (and other static and 
>> >> run-time diagnostic tools) would have to follow that definition - and it 
>> >> cannot distinguish between coding errors and intentional code.
>> >
>> >You still don't see the fundamental flaw in this assumption. So stating
>> >it directly: Fully-defined *includes* the definition of error behavior.
>> >*Of course* the compiler and/or runtime environment can detect errors,
>> >because they are defined as errors.
>> 
>> From what I can tell, David Brown majored in marketing as an undergrad,
>> then went to Business School and probably has an MBA.  He probably took one
>> or two computer course along the way.
>> 
>> Marketing (and B School) are all about making silk purses out of sow's ears.
>> 
>> That is what he has done (or at least attempted to do) in this thread.
>> Sell us sh*t as a feature.
>> 
>> There's good money in it.  I don't blame him for his efforts.
>> 
> It is, however, better to say that the results of

Please don't feed the troll.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#150693

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-03-19 15:58 +0100
Message-ID<vtdckg-3fe2.ln1@mail.home.palmen-it.de>
In reply to#150691
* Malcolm McLean <malcolm.arthur.mclean@gmail.com>:
> It is, however, better to say that the results of
> 
> int array10];
> array[10] = 42;
> 
> are "undefined", rather than that a 42 must be written to the position
> one past the array. That means that a good compiler can trap.

Sure! If your argument is to better have undefined behavior than defined
dangerous behavior, who wouldn't agree.

From an exclusive debugging perspective, the best would still be a
defined behavior of
- a program termination with diagnostic, or
- aborting the action and throwing an exception, if you want to go down
  *that* road.

Most modern languages do something in line with this. It requires a
runtime environment doing checks, which uses RAM and CPU cycles.

C doesn't want that, and I personally like that. But that's no reason to
sell UB as an advantage *per se*. It's a tradeoff, a price you pay.

-- 
 Dipl.-Inform. Felix Palmen  <felix@palmen-it.de>   ,.//..........
 {web}  http://palmen-it.de  {jabber} [see email]   ,//palmen-it.de
 {pgp public key}     http://palmen-it.de/pub.txt   //   """""""""""
 {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A

[toc] | [prev] | [next] | [standalone]


#150697

FromDavid Brown <david.brown@hesbynett.no>
Date2020-03-19 16:26 +0100
Message-ID<r502ua$2u2$1@dont-email.me>
In reply to#150693
On 19/03/2020 15:58, Felix Palmen wrote:
> * Malcolm McLean <malcolm.arthur.mclean@gmail.com>:
>> It is, however, better to say that the results of
>>
>> int array10];
>> array[10] = 42;
>>
>> are "undefined", rather than that a 42 must be written to the position
>> one past the array. That means that a good compiler can trap.
> 
> Sure! If your argument is to better have undefined behavior than defined
> dangerous behavior, who wouldn't agree.

Apparently, lots of people - especially the "let's define behaviours for 
C's undefined behaviours" group.  You are a little unusual in wanting to 
make the UB's into run-time errors - most want to define the operations 
as doing the "obvious thing for the hardware", believing the result to 
be safer and just as efficient.  Fairly obviously, they are wrong on 
both counts.

> 
>  From an exclusive debugging perspective, the best would still be a
> defined behavior of
> - a program termination with diagnostic, or
> - aborting the action and throwing an exception, if you want to go down
>    *that* road.
> 

No.  The best from a debugging perspective would be to define it as a 
compile-time error where it can be identified by the compiler, a static 
analyser error where it can be identified by static analysis, and a 
run-time error if it can't be spotted until run time.  I'm not really 
sure how you'd define that one.

I suppose you could say that it would be defined as a run-time error, 
but tools are allowed (indeed, encouraged) to warn you if a run-time 
error is inevitable in the code.

A better way, is to say that this kind of thing is undefined behaviour 
and have tools that provide debugging modes and sanitizers that add 
run-time checks.  This gives you the best of all possible worlds, and is 
what we have today with C (within the limitations of the tools, of course).

> Most modern languages do something in line with this. It requires a
> runtime environment doing checks, which uses RAM and CPU cycles.

For some kinds of code, the overhead here is /huge/.  The compiler can 
no longer re-arrange "x + y + z" into "x + (y + z)", or any one of a 
range of strength reductions and manipulations.  It can't vectorise 
code.  It has to add overflow checks everywhere, crippling super-scaler 
performance.  The list of things that you can't do grows fast.

The sole reason that languages with good runtime checks have reasonable 
speed is that the runtime code is implemented in C (or an unchecked 
version of some other language), without the need of such checks.

And for many modern languages, they try to avoid the possibility of such 
errors occurring in the first place.  If you don't have pointers, you 
avoid many kinds of UB.  If your integer types grow as needed, there is 
no overflow.

This can all be a good thing.  (I use Python a lot on PC's.)  But it 
would be a bad thing in C.

> 
> C doesn't want that, and I personally like that. But that's no reason to
> sell UB as an advantage *per se*. It's a tradeoff, a price you pay.
> 

UB is a /benefit/ in C.  It would not be a benefit in Python, but it is 
in C.

[toc] | [prev] | [next] | [standalone]


#150695

FromDavid Brown <david.brown@hesbynett.no>
Date2020-03-19 16:08 +0100
Message-ID<r501ua$rl0$1@dont-email.me>
In reply to#150690
On 19/03/2020 15:34, Kenny McCormack wrote:
> In article <s2bckg-ngl.ln1@mail.home.palmen-it.de>,
> Felix Palmen <felix@palmen-it.de> wrote:
>> * David Brown <david.brown@hesbynett.no>:
>>> If the behaviour were defined, the compiler (and other static and
>>> run-time diagnostic tools) would have to follow that definition - and it
>>> cannot distinguish between coding errors and intentional code.
>>
>> You still don't see the fundamental flaw in this assumption. So stating
>> it directly: Fully-defined *includes* the definition of error behavior.
>> *Of course* the compiler and/or runtime environment can detect errors,
>> because they are defined as errors.
> 
>  From what I can tell, David Brown majored in marketing as an undergrad,
> then went to Business School and probably has an MBA.  He probably took one
> or two computer course along the way.
> 
> Marketing (and B School) are all about making silk purses out of sow's ears.
> 
> That is what he has done (or at least attempted to do) in this thread.
> Sell us sh*t as a feature.
> 
> There's good money in it.  I don't blame him for his efforts.
> 

While I am wary of feeding obvious trolls, your imagination is 
impressive when trying to find ways to insult or ridicule people, but 
correspondingly lacking about what people might actually think.  Has it 
never occurred to you that I might honestly /like/ undefined behaviour 
in C, and think it is a good thing - at least for people who understand 
it and its implications, and are able to code accordingly?

Please don't judge others by your own poor standards.

[toc] | [prev] | [next] | [standalone]


#150709 — Troll, gadfly, whatever... (Was: "How one word broke C")

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2020-03-21 11:08 +0000
SubjectTroll, gadfly, whatever... (Was: "How one word broke C")
Message-ID<r54sjm$2gl$1@news.xmission.com>
In reply to#150695
In article <r501ua$rl0$1@dont-email.me>,
David Brown  <david.brown@hesbynett.no> wrote:
...
>While I am wary of feeding obvious trolls,

You can call me a troll all you want.  Troll, truthteller, gadfly,
whatever, it's all the same to me.

>your imagination is 
>impressive when trying to find ways to insult or ridicule people,

Well, thank you for that.  Much appreciated.

But here's the thing: how could you possibly take my describing you as a
marketing/Business School genius as an "insult"?  Back in the day - in the
days when I am assuming you were in school - this was what everybody strove
for.  This was the creme de le creme.  Us mere mortals in substantive
areas, were looked down upon as not being smart enough for B school.

>but 
>correspondingly lacking about what people might actually think.  Has it 
>never occurred to you that I might honestly /like/ undefined behaviour 
>in C, and think it is a good thing 

I never doubted that you do.  True marketing geniuses actually believe
their own press releases...  The better you are at fooling yourself, the
better and more effective you will be at fooling others.

Look at our current Orange Menace for proof positive of this.

-- 
The randomly chosen signature file that would have appeared here is more than 4
lines long.  As such, it violates one or more Usenet RFCs.  In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
	http://user.xmission.com/~gazelle/Sigs/Windows

[toc] | [prev] | [next] | [standalone]


#150710 — Re: Troll, gadfly, whatever... (Was: "How one word broke C")

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-03-21 04:50 -0700
SubjectRe: Troll, gadfly, whatever... (Was: "How one word broke C")
Message-ID<0c0e9360-3a45-4c9a-8289-8e3a7fab32a0@googlegroups.com>
In reply to#150709
On Saturday, 21 March 2020 11:08:48 UTC, Kenny McCormack  wrote:
ll, thank you for that.  Much appreciated.
> 
> But here's the thing: how could you possibly take my describing you as a
> marketing/Business School genius as an "insult"?  Back in the day - in the
> days when I am assuming you were in school - this was what everybody strove
> for.  This was the creme de le creme.  Us mere mortals in substantive
> areas, were looked down upon as not being smart enough for B school.
> 
Our business is half technical people like myself, half marketing
people. We need each other, without us there would be no software to
sell, without them, we wouldn't sell much. 

[toc] | [prev] | [next] | [standalone]


#150694

FromDavid Brown <david.brown@hesbynett.no>
Date2020-03-19 16:04 +0100
Message-ID<r501mo$puk$1@dont-email.me>
In reply to#150689
On 19/03/2020 15:10, Felix Palmen wrote:
> * David Brown <david.brown@hesbynett.no>:
>> If the behaviour were defined, the compiler (and other static and
>> run-time diagnostic tools) would have to follow that definition - and it
>> cannot distinguish between coding errors and intentional code.
> 
> You still don't see the fundamental flaw in this assumption. So stating
> it directly: Fully-defined *includes* the definition of error behavior.
> *Of course* the compiler and/or runtime environment can detect errors,
> because they are defined as errors.
> 

If it is defined as throwing an error or an exception, then it is not an 
error that can be caught by the compiler - it has a defined run-time 
behaviour, so the code must be generated to have that run-time behaviour.

It can be caught at run-time, of course.  (Unless, as some programmers 
do, someone has put a "catch all" at the highest level of the program.)


But I certainly agree that defining the behaviour as an error is a much 
more useful way to find bugs than defining it in some easy-to-implement 
way (such as defining integer overflow to wrap).  Defining it as an 
error is, however, a massive performance hit for code that could 
otherwise be simple and efficient.

[toc] | [prev] | [next] | [standalone]


#150696

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-03-19 16:16 +0100
Message-ID<60fckg-ukt2.ln1@mail.home.palmen-it.de>
In reply to#150694
* David Brown <david.brown@hesbynett.no>:
> But I certainly agree that defining the behaviour as an error is a much 
> more useful way to find bugs than defining it in some easy-to-implement 
> way (such as defining integer overflow to wrap).  Defining it as an 
> error is, however, a massive performance hit for code that could 
> otherwise be simple and efficient.

Of course! Although on many modern platforms, this "massive performance
hit" isn't so massive any more in practice, I *do* like C exactly for
not carrying such a bloated runtime environment. At the time C was first
specified, UB was probably the only sane choice. Nowadays, you could
argue about that.

I just opposed your claim that UB in itself is a good thing and not a
cost. It is a cost, but there are good reasons you might want to pay it.
And yes, a fully defined language *can* be worse, if the defined
behaviors are bad. But that isn't the normal case :)

-- 
 Dipl.-Inform. Felix Palmen  <felix@palmen-it.de>   ,.//..........
 {web}  http://palmen-it.de  {jabber} [see email]   ,//palmen-it.de
 {pgp public key}     http://palmen-it.de/pub.txt   //   """""""""""
 {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A

[toc] | [prev] | [next] | [standalone]


#150705

FromRichard Damon <Richard@Damon-Family.org>
Date2020-03-19 23:36 -0400
Message-ID<lTWcG.486873$db6.283078@fx33.iad>
In reply to#150696
On 3/19/20 11:16 AM, Felix Palmen wrote:
> I just opposed your claim that UB in itself is a good thing and not a
> cost. It is a cost, but there are good reasons you might want to pay it.
> And yes, a fully defined language *can* be worse, if the defined
> behaviors are bad. But that isn't the normal case :)

EVERYTHING comes with a cost (TANSTAAFL). It is always the case that we
compare cost to benefits to decide if something is good.

Sometimes costs and benefits are easy to measure, sometimes it takes a
bit of work to figure out what they are and figure out how to quantify
them, and sometimes we just can't reduce them to something quantifiable.

By similar logic to what you are using, it could be said that the error
messages are a cost. (Have you thought what changes would need to be
done to provide rigid bounds checking in C without limiting any of the
valid accesses?, it isn't that simple).

[toc] | [prev] | [next] | [standalone]


#150703

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-03-19 18:13 -0400
Message-ID<r50qqj$iag$1@dont-email.me>
In reply to#150688
On 3/19/20 10:02 AM, David Brown wrote:
> On 18/03/2020 23:27, Felix Palmen wrote:
>> * David Brown <david.brown@hesbynett.no>:
>>> You are imagining that undefined behaviour is a "cost" - it is not.  It
>>> is a bonus - a benefit that C and C++ programmers get, that programmers
>>> of other languages often do not have.
>>
>> No, it is a cost paid for a bonus.
> 
> (I'm concerned here with undefined behaviour at run-time, rather than 
> things like declaring a function in one place and defining it in another 
> place with different parameters.  Good code structure and compiler flags 
> eliminate that kind of thing for the most part.)
> 
> 
> There is no cost.

You're arguing about UB vs. defining the behavior to be correct in some
fashion. He's arguing about UB vs. defining the behavior to be reliably
erroneous - i.e. generating a diagnostic or raising a signal. Undefined
behavior is a cost relative to such an error message - when the code is
erroneous, who wouldn't prefer a runtime error message rather than
formatting the hard disk? However, it's a cost that is offset by it's
corresponding benefits in terms of better performance.

> Look, your aim is to write bug-free code, agreed?
> 
> So the two concerns are how does UB affect correct code once it is 
> written, and how does UB affect finding or avoiding the bugs in order to 
> get correct code?
> 
> First, consider correct code.  This code does not let signed integer 
> operations overflow, since any answer would be wrong.  It does not 
> access arrays out of bounds, since that could not possibly be correct. 
> It does not dereference null pointers, or free pointers twice, or use 
> any function or operator in the language outside of the specifications 
> (given by the standards and the implementation).  What does it matter if 
> dereferencing a null pointer launches nasal demons?  Nothing at all, 
> since your code never dereferences a null pointer.  UB is /zero/ cost 
> for correct code.  (And because it allows more optimisations, it is a 
> positive benefit.)
> 
> Then consider finding bugs.  Undefined behaviour is always a bug - and 
> thus compilers and analysis tools can complain about them and give 
> warnings about them.  Of course no tool can find every fault, but they 
> are getting steadily better at finding more.  And you can have run-time 
> tools such as specialised memory allocators and "sanitizers" that add 
> run-time checks of various types in order to catch a lot of undefined 
> behaviour.
> 
> If the behaviour were defined, the compiler (and other static and 
> run-time diagnostic tools) would have to follow that definition - and it 
> cannot distinguish between coding errors and intentional code.

Not if the defined behavior was to terminate the program after
generating some kind of diagnostic. Reliably generating such diagnostics
at runtime might carry significant costs in terms of reduced performance
- but that's precisely his point. The reason why undefined behavior is
preferred over defining the behavior as generating a diagnostic IS
performance - and as such, whether the benefits justify the cost is a
matter of opinion, depending upon the relative importance you place on
those costs and those benefits.

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web