Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #150634 > unrolled thread
| Started by | Lynn McGuire <lynnmcguire5@gmail.com> |
|---|---|
| First post | 2020-03-17 14:29 -0500 |
| Last post | 2020-03-24 19:41 -0400 |
| Articles | 20 on this page of 43 — 17 participants |
Back to article view | Back to comp.lang.c
"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 →
| From | Eli the Bearded <*@eli.users.panix.com> |
|---|---|
| Date | 2020-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]
| From | Philipp Klaus Krause <pkk@spth.de> |
|---|---|
| Date | 2020-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-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]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2020-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]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-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]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-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]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2020-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]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-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]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2020-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]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-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]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2020-03-21 11:08 +0000 |
| Subject | Troll, 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]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-03-21 04:50 -0700 |
| Subject | Re: 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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-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]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2020-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-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