Re: Bash arithmetic doesn't give error message on wrap.
Richard Neill <[EMAIL PROTECTED]> writes: > Are you sure this isn't comparable? After all, in both cases, the user has > submitted something to which bash cannot give a sensible answer. In the > integer-overflow case, bash simply returns the wrong answer, with no > warning. The answer is not really wrong, it's the same you get from the equivalent expression when evaluated in C. > But in the octal case, bash (quite correctly, and helpfully) > prints a warning. It's not a warning, it's an error (and the whole command containing the expansion is aborted). > If bash were to be consistent, then it should display no error message in > the case of $((3+078)); This is a syntax error, so there is no sensible meaning attached to it. A syntax error is something quite different than an undefined behaviour. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash arithmetic doesn't give error message on wrap.
Andreas Schwab wrote: > Richard Neill <[EMAIL PROTECTED]> writes: > > Are you sure this isn't comparable? After all, in both cases, the user has > > submitted something to which bash cannot give a sensible answer. In the > > integer-overflow case, bash simply returns the wrong answer, with no > > warning. > > The answer is not really wrong, it's the same you get from the equivalent > expression when evaluated in C. Let me phrase this in a different way. In the case of the syntax error "08" bash is doing the input text processing and therefore has complete control and capability to generate an error message. But most importantly the program cannot be executed because it the input is invalid. It can't get to the execution phase because of the input error. In the case of 40*40 bash is effectively sending the expression to the computer's math processor and reading the result back. The program is valid. The program is being executed. But because the underlying math processing in the cpu has an insufficient number of bits to hold the result an overflows occurs. The shell has less control in this case. The shell itself is not doing the multiplication. The shell is relying upon the cpu to execute the code of the multiplication and to return the result, which it does. To the shell everything appears to operate fine. Avoiding overflow is actually a very difficult problem. People have been working with and around overflow issues for years and years. There is no clear "right" answer. On some cpus the result is done one way and on others the result is done a different way. It is in these cases where typically POSIX would give up and declare it undefined behavior. This is why "40*40" appears as a completely different problem than "08". About the only way for bash to avoid it would be to include a full arbitrary precision math library to evaluate these expressions itself. But that would slow the shell down by a large amount and it would make the shell much bigger than it is today. Both of those things would cause people problems. The entire reason cpus have math processors is because these operations can be quite slow when done in software. To give some additional weight to this, note that perl also uses the underlying cpu for numerical computations. So this is the same issue as would be true in Perl. Or in C/C++ too. perl -e 'printf("%d\n",40*40);' -2446744073709551616 However a counter point is that Ruby does include an arbitrary precision math library. ruby -e 'puts (40*40).to_s' 1600 Bob ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash arithmetic doesn't give error message on wrap.
Bob Proulx wrote: Andreas Schwab wrote: Richard Neill <[EMAIL PROTECTED]> writes: Are you sure this isn't comparable? After all, in both cases, the user has submitted something to which bash cannot give a sensible answer. In the integer-overflow case, bash simply returns the wrong answer, with no warning. The answer is not really wrong, it's the same you get from the equivalent expression when evaluated in C. Let me phrase this in a different way. 8< [OK - agreed. Thanks for your explanation] Avoiding overflow is actually a very difficult problem. People have been working with and around overflow issues for years and years. There is no clear "right" answer. On some cpus the result is done one way and on others the result is done a different way. It is in these cases where typically POSIX would give up and declare it undefined behavior. This is why "40*40" appears as a completely different problem than "08". I thought testing for overflow was quite simple? Isn't it just a case of looking at the carry-bit, and seeing whether it gets set? If so, then the warning message would be a two-line patch to the code. That said, I don't know enough about CPU internals to know what the carry-bits do with multiplication. (Addition/Subtraction overflows just change the carry-flag; Integer Division never suffers from overflows). About the only way for bash to avoid it would be to include a full arbitrary precision math library to evaluate these expressions itself. I wasn't suggesting that! We have bc anyway. I was only suggesting that, when the CPU detects an overflow, bash could pass on the warning. But that would slow the shell down by a large amount and it would make the shell much bigger than it is today. Both of those things would cause people problems. The entire reason cpus have math processors is because these operations can be quite slow when done in software. To give some additional weight to this, note that perl also uses the underlying cpu for numerical computations. So this is the same issue as would be true in Perl. Or in C/C++ too. perl -e 'printf("%d\n",40*40);' -2446744073709551616 Yes... but that's actually the %d doing it. Perl would automatically convert to a float. Eg $ perl -e 'print(40*40);' 1.6e+19 Thanks very much for your explanation. Best wishes, Richard ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash arithmetic doesn't give error message on wrap.
[EMAIL PROTECTED] (Bob Proulx) wrote: > On some cpus the result is done one way and on others the result is > done a different way. It is in these cases where typically POSIX > would give up and declare it undefined behavior. Yes, and those are exactly the cases where a message would be helpful, to let the user know that the result is not portable, and does not necessarily indicate what the user thinks it does. Undefined behavior makes sense for C, since C is essentially a "portable assembly language". For a higher-level language, it makes considerably less sense. And in any case, it does not require the implementation to be unhelpful. > About the only way for bash to avoid it would be to include a full > arbitrary precision math library to evaluate these expressions > itself. It depends on the goal. If the goal is to produce a mathematically correct result, then yes. But if the goal is only to detect overflow and print a warning, then that can still be done without arbitrary precision. paul ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash arithmetic doesn't give error message on wrap.
Richard Neill <[EMAIL PROTECTED]> wrote: > I thought testing for overflow was quite simple? > Isn't it just a case of looking at the carry-bit, and seeing whether it > gets set? That's usually how it's done in assembly. In C, it's somewhat more compilcated. For example: result=a*b; if (result/a!=b) { report overflow; } paul ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash arithmetic doesn't give error message on wrap.
[EMAIL PROTECTED] (Paul Jarc) writes: > Richard Neill <[EMAIL PROTECTED]> wrote: >> I thought testing for overflow was quite simple? >> Isn't it just a case of looking at the carry-bit, and seeing whether it >> gets set? > > That's usually how it's done in assembly. In C, it's somewhat more > compilcated. For example: > result=a*b; > if (result/a!=b) { report overflow; } That won't work, since (signed integer) overflow is undefined in C. A compiler is allowed to optimize the condition to false. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash arithmetic doesn't give error message on wrap.
Andreas Schwab <[EMAIL PROTECTED]> wrote: > [EMAIL PROTECTED] (Paul Jarc) writes: >> result=a*b; >> if (result/a!=b) { report overflow; } > > That won't work, since (signed integer) overflow is undefined in C. A > compiler is allowed to optimize the condition to false. Right, operations would have to be performed in unsigned arithmetic and then adjusted for the proper sign, range chaecking, etc., to get signed results. paul ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash