Poll

Do you think hanging a program in an infinite loop is allowable under the C language term "undefined behaviour"?

Yes
21 (70%)
No
9 (30%)

Total Members Voted: 30

Author Topic: Should C language "undefined behaviour" cover crashing/hanging?  (Read 35776 times)

0 Members and 4 Guests are viewing this topic.

Offline HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1922
  • Country: gb
Should C language "undefined behaviour" cover crashing/hanging?
« on: October 27, 2022, 03:26:44 pm »
I have been pondering this question for a few days.

After what started as an effort to write my own stripped-down, smaller printf() implementation after discovering I was nearly out of space on my MCU, I got nerd-sniped into also re-writing more efficient alternatives to my platform's C standard library 32-bit unsigned division and modulus software routines in assembly (they are used by ultoa(), which is used by my printf()). As part of testing my substitutes, I wanted to compare them to the behaviour of the standard library routines. So I wrote some test cases - some of which included dividing by zero. But to my surprise I discovered that the standard library implementation of modulus has a problem where the algorithm gets stuck in an infinite loop if the divisor is zero.

After reporting this to the maintainers, the opinion was given that it wasn't a problem, as "undefined behaviour" allows for that. I think that's a relatively cynical interpretation, and in my opinion "undefined behaviour" should - at least in this context - be that the result is undefined.

What say you lot in the peanut gallery? :)
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12468
  • Country: us
    • Personal site
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #1 on: October 27, 2022, 03:59:23 pm »
It is allowed. "Result" in the context of a C spec is the state of the program, not an actual result returned by the function. So, getting stuck in a loop is a valid result as well.

Not only that, I've seen cases where GCC would replace the whole body of the function with a single instruction - UDF (architecturally undefined instruction on ARM) just because the function used an uninitialized pointer for a buffer and the rest of the code depended on that. So, the compiler eliminated all the code because as far as the spec goes, the result is the same. It could have itself replaced the whole function with a while (1);. It would have been just as valid.

In fact, I would call this behaviour desiderable in may cases. If the code gets stuck in the place where the issue is "detected", it makes it easier to debug. If the function just subtly returns the wrong result, you may have a lot of fun chasing it. Although in a more modern language, I would design in explicit checks and try to have as few undefined things as possible, ideally none. But this is not what C is, and it is to late to change.
« Last Edit: October 27, 2022, 04:16:11 pm by ataradov »
Alex
 
The following users thanked this post: thm_w, newbrain, sokoloff, MK14, Jacon

Offline MK14

  • Super Contributor
  • ***
  • Posts: 5385
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #2 on: October 27, 2022, 04:35:44 pm »
opinion "undefined behaviour" should - at least in this context - be that the result is undefined.

What say you lot in the peanut gallery? :)

Nasal demons, might jump out, throw peanuts at you from the gallery, until you make a Riemann sphere.

Edit: Ideally, it should have produced a compiler error (perhaps in an ideal world), failing that a run time error (if possible, e.g. Divide by zero error).  But really, 'undefined behavior', can do just about anything, and probably more still.  So an infinite loop, is one example, of what it can do.
« Last Edit: October 27, 2022, 04:53:33 pm by MK14 »
 

Offline HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1922
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #3 on: October 27, 2022, 05:09:45 pm »
See, the thing is that I totally understand the arguments that "undefined behaviour" refers to the program state. That for example, what happens when accessing beyond the end of an array is also undefined behaviour - that it may corrupt other memory and thus potentially alter the state of the program.

But what would you say when given the following scenario? What if this code will not hang the program, but give a wrong result:

Code: [Select]
a = 12345
b = 0;
c = a % b;

And this code will hang the program in an endless loop:

Code: [Select]
a = 12345
b = 0;
c = a % b;

What do you mean, "there's no difference"?

Oh, I forgot to mention the first one is using unsigned int variables, and the other unsigned long. You see, on the platform in question, the former is performed with the CPU's native division instructions, whereas the latter is performed with a software routine that has the aforementioned behaviour. The two are inconsistent with each other for what is the same arithmetic operation. I think there is some merit in things failing in a predictable way when performing the same operation.
 
The following users thanked this post: edavid

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12468
  • Country: us
    • Personal site
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #4 on: October 27, 2022, 05:20:45 pm »
I think there is some merit in things failing in a predictable way when performing the same operation.
Yes, there is, but this is not what C specification says. And compilers implement the specification. So, your complaint is to the standards people, not the compiler writers. And a lot of people have complaints to them, but they have their reasons.

All you can do is use a different language that does not have this behaviour.

If we are talking in abstract, I agree with you 100%. But when it comes to C, there is a well defined specification in place, it is fixed. You can implement "more robust" C, but it will likely break exiting software and there will be no market for it.
« Last Edit: October 27, 2022, 05:22:21 pm by ataradov »
Alex
 
The following users thanked this post: newbrain, MK14

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #5 on: October 27, 2022, 05:22:13 pm »
in a more modern language, I would design in explicit checks and try to have as few undefined things as possible, ideally none. But this is not what C is, and it is to late to change.

yup, yet an other point for my-c  :D
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline MarginallyStable

  • Regular Contributor
  • *
  • Posts: 92
  • Country: us
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #6 on: October 27, 2022, 06:02:52 pm »
Not sure why you are trying to define "undefined behavior". It is exactly what it is.
 
The following users thanked this post: MK14

Offline alm

  • Super Contributor
  • ***
  • Posts: 2903
  • Country: 00
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #7 on: October 27, 2022, 06:32:43 pm »
Undefined behavior covers anything including the destruction of the machine (look up halt and catch fire).

If you don't want this to happen, then it's your job as C programmer to make sure you never trigger this behavior, for example by checking a divisor is non-zero before dividing. Undefined in the C spec equivalent of your doctor saying "If you get a headache after drinking five cups of coffee, then don't drink five cups of coffee".

If you want the language to take care of this instead of you, use a higher level language that defines a zero division exception or something like that.
 
The following users thanked this post: MK14

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #8 on: October 27, 2022, 07:01:47 pm »
Undefined behavior covers anything including the destruction of the machine (look up halt and catch fire).

If you don't want this to happen, then it's your job as C programmer to make sure you never trigger this behavior, for example by checking a divisor is non-zero before dividing. Undefined in the C spec equivalent of your doctor saying "If you get a headache after drinking five cups of coffee, then don't drink five cups of coffee".

If you want the language to take care of this instead of you, use a higher level language that defines a zero division exception or something like that.

The problem is that very few programmers understand all the subtle and surprising causes of "undefined behaviour". Most think they do, of course :( That was famously illustrated when Hans Boehm thought it worthwhile to write a paper pointing out that you couldn't write a threading library in C - too many people presumed or "thought" you could.

C++ is worse. The committee defining the language didn't understand what they had created until their noses were rubbed in it by a short program that spat out the sequence of prime numbers while it ws being compiled. That's right; the design committee hadn't realised C++ templates are a Turing complete language in themselves - and that some valid C++ programs could never finish being compiled.

The least unsatisfactory alternative with C is to adhere to one of the relatively benign subsets of C, e.g.  MISRA.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: MK14

Offline HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1922
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #9 on: October 27, 2022, 07:08:31 pm »
Yes, there is, but this is not what C specification says. And compilers implement the specification. So, your complaint is to the standards people, not the compiler writers.

I suppose you're right. I guess that's what happens when you try to mould a standard around a lot of existing and varied implementation.



Don't get me wrong, I'm not criticising the C language as a whole. If I were upset about this stuff, I wouldn't be using it. I know it's the programmer's job to avoid triggering undefined behaviour (e.g. check your divisor values first, your array bounds, that pointers are valid, etc.). I just wish in some areas (like this) there was more predictability and consistency. Speaking of which, further to my example above, I just remembered one more thing about this scenario: the routine for 32-bit division (as opposed to modulus) doesn't even have the same issue! It uses a different algorithm and is perfectly fine with a divisor of zero! Even more inconsistency. ::)

I think the whole thing about "undefined behaviour" meaning any random event could occur - up to and including your computer exploding, your hair turning purple, or being haunted by evil spirits - needs to have some kind, pragmatic consideration applied. Not for compiler or library writers to just shrug their shoulders and say "we're okay with letting random shit happen even though some of it is under our control".

Edit: That last sentence also gave rise to this thought: as I understand it, a lot of C undefined behaviour is due to having to allow for the idiosyncrasies of varied hardware. The circumstances that lead to undefined behaviour may be uncontrollable due to the nature of the platform code is running on. But when the behaviour is entirely within an entity's control (e.g. add a line of code to a library routine to perform a zero check), I think that is when pretence of "we can't help it" needs to go away.
« Last Edit: October 27, 2022, 07:17:04 pm by HwAoRrDk »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12468
  • Country: us
    • Personal site
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #10 on: October 27, 2022, 07:13:23 pm »
needs to have some kind, pragmatic consideration applied.
This is called "defining the behaviour". Once you limit a set of outcomes, you defined the behaviour.

As a rational human being you can safely assume that your C program won't implode the universe. But you can't put that into spec.

The reason it is done this way is that they basically reserve the right to not handle corner cases, especially ones that are different between architectures. This itself limits realistically possible outcomes.
« Last Edit: October 27, 2022, 07:15:01 pm by ataradov »
Alex
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6920
  • Country: es
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #11 on: October 27, 2022, 07:27:59 pm »
You can't apply rules to undefined behavior, means exactly that, might work, crash, overwrite other variables, execute random code...
You might be lucky if the CPU supports exceptions.
« Last Edit: October 27, 2022, 07:29:36 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12468
  • Country: us
    • Personal site
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #12 on: October 27, 2022, 07:28:52 pm »
I think that is when pretence of "we can't help it" needs to go away.
"We don't check" is the defined behavior though. And this is good because it lets you write more optimal code. If you are passing some variable around, you as a programmer can check it once and then let the code assume the operation would be defined.

Again, other higher level languages do those checks, they are generating less efficient code. You pick which one you want.

This is similar to memcpy() and overlapping buffers. The function is explicit that it might break if the buffers overlap. This allows for a more efficient implementation. If you as a user can't guarantee that and don't want to check, then use memmove(). But don't make everyone else's code slower by default.
« Last Edit: October 27, 2022, 07:32:33 pm by ataradov »
Alex
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12468
  • Country: us
    • Personal site
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #13 on: October 27, 2022, 07:35:55 pm »
And as a compiler author you can define the behaviour, of course. This is not against the spec. For GCC, you have -fsanitize=integer-divide-by-zero and generally -fsanitize=undefined. The compiler would generate those checks for you. Your code would be bigger and slower as a result, but if that's what you want, then use those sanitation options.

See https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Instrumentation-Options.html for more information.
Alex
 
The following users thanked this post: MK14

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #14 on: October 27, 2022, 07:59:28 pm »
"We don't check" is the defined behavior though. And this is good because it lets you write more optimal code.

If I'm allowed to produce code that doesn't give the correct output, then I can produce extremely small and performant code very quickly.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12468
  • Country: us
    • Personal site
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #15 on: October 27, 2022, 08:03:12 pm »
If I'm allowed to produce code that doesn't give the correct output, then I can produce extremely small and performant code very quickly.
Exactly. Thant's what compiler did in my case where it replaced a huge function with UDF instruction. The result of executing my huge code and this one instruction is the same, so why do more?

This only happened because undefined behavior was detected at compile-time, of course (there is probably some combination of warning flags that would have warned me, but they were not a part of -W -Wall). In run-time you just end up with a really unpredictable behavior that depends on the underlying architecture.

Compilers free to do this, so don't write code that contains UB.
« Last Edit: October 27, 2022, 08:06:08 pm by ataradov »
Alex
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17789
  • Country: fr
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #16 on: October 27, 2022, 09:26:39 pm »
Hanging? How can you know that it's not actually a desired behavior in a given situation? (Hint: sometimes it is.)
How could it ever be "undefined behavior"? How could you want a loop to be undefined behavior in any situation? And how do you think "hanging" should be defined exactly?
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #17 on: October 27, 2022, 09:37:45 pm »
If I'm allowed to produce code that doesn't give the correct output, then I can produce extremely small and performant code very quickly.
Exactly. Thant's what compiler did in my case where it replaced a huge function with UDF instruction. The result of executing my huge code and this one instruction is the same, so why do more?

This only happened because undefined behavior was detected at compile-time, of course (there is probably some combination of warning flags that would have warned me, but they were not a part of -W -Wall). In run-time you just end up with a really unpredictable behavior that depends on the underlying architecture.

Compilers free to do this, so don't write code that contains UB.

Unfortunately there are so many subtle ways to invoke UB, and most people don't know all of them.
Or don't realise when they have invoked UB.
Or don't realise when the library they are using invokes UB internally.
Or don't realise when their use of a library invokes UB.
Or don't realise that an upgraded compiler now detects and makes use of UB.

Basically UB is fragile.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12468
  • Country: us
    • Personal site
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #18 on: October 27, 2022, 09:43:11 pm »
I fully agree. And I don't like that UB exists. But I can hardly blame people in 1972 for not thinking about it. And I can't blame standard maintainers for not wanting to break things. It is better that way. Look at Python developers, they are happily breaking things all the time to male it "better".

C is what it is. Although I personally don't like most of the new languages, there are good arguments for not using C anymore, especially for really critical stuff.

I would like to se improved version of C, but unfortunately all attempts at this instantly grow a ton of features and become bloated and unusable.
Alex
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #19 on: October 27, 2022, 10:08:28 pm »
I fully agree. And I don't like that UB exists. But I can hardly blame people in 1972 for not thinking about it. And I can't blame standard maintainers for not wanting to break things. It is better that way. Look at Python developers, they are happily breaking things all the time to male it "better".

C is what it is. Although I personally don't like most of the new languages, there are good arguments for not using C anymore, especially for really critical stuff.

I would like to se improved version of C, but unfortunately all attempts at this instantly grow a ton of features and become bloated and unusable.

Agreed. (How boring!)

Except C is no longer a svelte lean language - "bloated" and "unusable" do apply to C. (C++ is even worse)

Multicore CPUs are forcing the adoption of new languages, and about time too :)
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #20 on: October 27, 2022, 10:46:40 pm »
I fully agree. And I don't like that UB exists. But I can hardly blame people in 1972 for not thinking about it. And I can't blame standard maintainers for not wanting to break things. It is better that way. Look at Python developers, they are happily breaking things all the time to male it "better".

C is what it is. Although I personally don't like most of the new languages, there are good arguments for not using C anymore, especially for really critical stuff.

I would like to se improved version of C, but unfortunately all attempts at this instantly grow a ton of features and become bloated and unusable.

don't blame? I do!
C sucks and can be fixed, just people don't do it without putting too much Ego burst into it!

People can blather things over and over in endless discussions.
I have already fixed the UB problem once and forever: my-C is *THE* solution for me.

It's no C++, it's not C with classes, it's 90% compatible with MISRA C & DO178{B,C} level {A, B}, and it doesn't have UB because it enforces monads.

Monads are *THE* key. Sure they look quirk, and the machine layer generates less efficient machine code (due to the nature of monads), but the language is more coherent and, better still, the generated code is more robust at run time.


The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online Marco

  • Super Contributor
  • ***
  • Posts: 7751
  • Country: nl
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #21 on: October 27, 2022, 10:53:34 pm »
When there is no good reason, don't cause unrecoverable program failure for unexpected input. It crashes rockets.
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #22 on: October 27, 2022, 11:01:10 pm »
Multicore CPUs are forcing the adoption of new languages, and about time too :)

The reason why I developed my-C is ... because there is no C compiler for R18200, a MIPS5 superscalar multicore prototype with tr-memory.

for complex projects like ... a filesystem, on a superscalar + out of order + Tr-memory architecture is something for which you can't have UBs if you want to write something working without spending your entire life on the debugger  :o :o :o

Seriously? I wonder how guys at IBM can collaborate with guys at GNU Gcc and guys at LINUX-dev to support POWER9 and POWER10 cores and their tr-memory  :o :o :o

The Linux kernel is still written in standard C, thus respect for those guys! They must be super-gurus!
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #23 on: October 27, 2022, 11:12:46 pm »
When there is no good reason, don't cause unrecoverable program failure for unexpected input. It crashes rockets.

I remember an ARING unit on a supersonic airplane: if you unplug the serial RS422 cable of the MTC bridge (or if something cuts the cable) ... ops, unexpected input, machine exception raised, and you see the whole MTC crashing.

Pray this doesn't happen when you fly faster than sound waves!
Pray this doesn't happen when you flying in the enemy area!

MTC means "mission tactical computer", it's super redundant, but since there are no monads behind the datatypes in the ISRs, well ... unplugging the cable is really something unexpected, not handled by anything, which, worse still is then subjected to undefined behavior.

That's why DO178B-levelA says you have to remove all the dead-code and adds extra care during the software testing activities.

What if the undefined behavior arm and shoot a missile? or eject the pilot?

(ok, here there are extra protections, but you get the point)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Re: Should C language "undefined behaviour" cover crashing/hanging?
« Reply #24 on: October 27, 2022, 11:15:57 pm »
the serial RS422 cable of the MTC bridge

To make you laugh: that cable is the logger cable.
So, you unplug the data logger, you crash the MTC.

Nice feature, ain't it  ;D ?
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->