Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001108 [1003.1(2016/18)/Issue7+TC2] Base Definitions and Headers Editorial Error 2016-12-09 17:00 2020-04-23 11:16
Reporter nsz View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Applied  
Name Szabolcs Nagy
Organization musl libc
User Reference
Section limits.h
Page Number
Line Number
Interp Status ---
Final Accepted Text Note: 0004094
Summary 0001108: LONG_MIN must be <= -2147483648
Description limits.h says

  LONG_MIN
  Minimum value for an object of type long.
  Maximum Acceptable Value: -2 147 483 647

but mrand48() and jrand48() apis return long which is specified to
be uniform in [ -2147483648, 2147483647 ]

so on a conforming implementation LONG_MIN <= -2147483648 must hold.
Desired Action change the LONG_MIN text to

Maximum Acceptable Value: -2 147 483 648

with CX shading (or add this with XSI shading, since mrand48 and jrand48 are XSI apis).

Tags issue8
Attached Files

- Relationships
parent of 0001197Closed Omission from 1108: LONG_MIN must be <= -2147483648 
has duplicate 0001177Closed Misstated permitted limits on signed types 

-  Notes
(0003512)
EdSchouten (reporter)
2016-12-09 18:40

Hey! Thanks for filing this defect. I guess this problem also applies to a64l() and l64a().

In http://austingroupbugs.net/view.php?id=1106 [^] I already proposed changing the prototype of jrand48() to use uint16_t instead of unsigned short. Maybe we should just leave the definition of LONG_MIN the way it is now, but fix up the functions to use int32_t while we're at it? I guess if you would design functions like these from scratch, you would have used int32_t anyway.
(0003513)
nsz (reporter)
2016-12-09 22:25

i think it's not reasonable to change function types now:

that can break abi so the symbol name has to change then too.
it can break a lot of source code as well because of the
incompatible type (which would depend on _XOPEN_SOURCE
macro definition).

if these apis were useful then a new variant of them could
be introduced under a new name, but i think it's better to
obsolete them instead.
(0004041)
geoffclare (manager)
2018-06-07 16:10

On P280 L9437 replace
<CX>Maximum Acceptable Value: −2 147 483 647</CX>
with
<CX>Maximum Acceptable Value: −2 147 483 648</CX>

At Line 9443 replace
Maximum Acceptable Value: −9 223 372 036 854 775 807
with
<CX>Maximum Acceptable Value: −9 223 372 036 854 775 808</CX>

At L9452 replace
Maximum Acceptable Value: −2 147 483 647
with
<CX>Maximum Acceptable Value: −2 147 483 648</CX>

At L9467 replace
Maximum Acceptable Value: −32 767
with
<CX>Maximum Acceptable Value: −32 768</CX>

After P282 L9539 (<limits.h>) add a new paragraph:
The maximum values for SCHAR_MIN, SHRT_MIN, LONG_MIN and LLONG_MIN differ from the C Standard because POSIX.1 requires two's complement representation for the corresponding integer types. The maximum value for INT_MIN differs both for that reason and because POSIX.1 requires that int has a width of at least 32 bits. See also the RATIONALE section for <stdint.h>.

On P282 L9543 (<limits.h>) add <stdint.h> to the SEE ALSO section.

On P348 L11817 (<stdint.h>) change:
An N-bit signed type has values in the range -2<sup>N-1</sup> or 1-2<sup>N-1</sup> to 2<sup>N-1</sup>-1, while an N-bit unsigned type has values in the range 0 to 2<sup>N</sup>-1
with
An N-bit signed type in two's complement representation has values in the range -2<sup>N-1</sup> to 2<sup>N-1</sup>-1, while an N-bit unsigned type has values in the range 0 to 2<sup>N</sup>-1.
<CX>While the C standard also permits signed integers in sign-magnitude or one's complement form, this standard requires an implementation to use two's complement representation for the standard integer types.</CX>

After P349 L11866 add a new paragraph with CX shading:
If the representation of any of the standard types short, int, long or long long is not the same as one of the above required types, an intN_t type with that representation shall be defined along with its uintN_t counterpart.

On P351-352 L11944-11965 (<stdint.h>) change all occurrences of:
-1)
to:
)
and add CX shading to the affected text in parentheses.

On P352 L11979 (<stdint.h>), change:
-65 535
to:
<CX>-65 536</CX>

On P354 L12040 (<stdint.h>), replace
(The POSIX standard explicitly requires 8-bit char and two's-complement arithmetic.)
with
Since the POSIX.1 standard explicitly requires 8-bit char with two's complement arithmetic, it is easier for application writers if the same two's complement guarantees are extended to all of the other standard integer types. Furthermore, in programming environments with a 32-bit long, some POSIX.1 interfaces, such as mrand48(), cannot be implemented if long does not use a two's complement representation.

On P567 L19829 (abs), replace
If the result cannot be represented, the behavior is undefined.
with
<CX>If the result cannot be represented, the result shall be {INT_MIN}.</CX>

On P567 L19838 (abs), replace
In two's-complement representation, the absolute value of the negative integer with largest magnitude {INT_MIN} might not be representable.
with
<CX>Since POSIX.1 requires a two's complement representation of int, the absolute value of the negative integer with the largest magnitude {INT_MIN} is not representable; but the rules of negation in two's complement arithmetic ensure that {INT_MIN} is returned.</CX>

On P1135 L38352 (imaxabs), replace
If the result cannot be represented, the behavior is undefined.
with
<CX>If the result cannot be represented, the result shall be {INTMAX_MIN}.</CX>

On P1135 L38361 (imaxabs), replace
The absolute value of the most negative number cannot be represented in two's complement.
with
<CX>Since POSIX.1 requires a two's complement representation of intmax_t, the absolute value of the negative integer with the largest magnitude {INTMAX_MIN} is not representable; but the rules of negation in two's complement arithmetic ensure that {INTMAX_MIN} is returned.</CX>

 On P1232 L41185 (labs), replace
If the result cannot be represented, the behavior is undefined.
with
<CX>If the result cannot be represented, the result shall be {LONG_MIN} for labs() or {LLONG_MIN} for llabs() .</CX>

On P1232 L41195 (labs APPLICATION USAGE), replace
None.
with
<CX>Since POSIX.1 requires a two's complement representation of long and long long, the absolute value of the negative integer with the largest magnitude {LONG_MIN} or {LLONG_MIN} is not representable; but the rules of negation in two's complement arithmetic ensure that {LONG_MIN} (for labs()) or {LLONG_MIN} (for llabs()) is returned.</CX>

On P3115 L104217 (printf), replace
twos-complement
with
two's complement
(0004050)
cmsmith (reporter)
2018-07-11 21:10

These changes seem to invalidate compilers for use in Unix/POSIX which use trap representations for int, long, etc., variables. I may be missing something, but, at least in the 2016 specification, I didn't see anything that precluded that. I know POSIX uses int8_t, int16_t, int32_t, etc., but those can be implemented using other data types (perhaps of the same size of int or long) but don't have the ability to store invalid values. I am not sure when mrand48() and jrand48() changed form the 2016 spec that lists the range as being from -2^31 to +2^31.
(0004051)
geoffclare (manager)
2018-07-12 08:13

Re: Note: 0004050 (last sentence), the range is specified as [-2^31,2^31) where the opening bracket is square indicating that the -2^31 is included while the closing bracket is round indicating that the 2^31 is not included in the range.
(0004052)
shware_systems (reporter)
2018-07-12 11:43

Re: 4050:
Those compilers are presuming it is required that -2^N is a trap representation on all platforms, and are therefore only suitable for a subset of C conforming platforms, as this is a reliance on undefined behavior, from POSIX perspective. It only guarantees the behavior within the limits *_MIN to *_MAX, not defines anything for values outside what has been specified. The C standard leaves it implementation-defined, and to clarify that ambiguity POSIX is, with this bug note, making it explicit it's a non-trap value for a given bit-width to be aligned with the majority of existing practice and other parts of the standards that require this.

This change does not really preclude those types of compilers, either, that I see. A platform can have additional compilation environments that document that this is what has been chosen as the C conforming behavior. This change just affects the standard POSIX environments getconf is required to report about and when _POSIX_C_SOURCE is defined. It was also brought up that there could possibly be more compilation environments defined, for trap and non-trap variants of 1s-complement and sign-magnitude, but since only one known processor family makes use of 1s-complement in hardware, and none sign-magnitude or 2s-complement with trap, this was not considered a priority.
(0004064)
eblake (manager)
2018-07-30 19:02

Mailing list traffic has complained about making abs(x) and friends well-defined for all x, on the grounds that it needlessly hurts compiler optimizations. For example, some compilers offer options such as -ftrapv vs. -fwrapv that can fine-tune whether abs(INT_MIN) behaves a specific way, whereas POSIX unilaterally requiring a specific behavior is at odds with that ability to fine-tune behavior.

Thus, this is a valid argument worth reopening the discussion on this bug, and limiting the changes to JUST making int and friends have twos-complement representation, without also requiring (as a much tighter restriction than C) that abs(INT_MIN) be well-defined.
(0004089)
geoffclare (manager)
2018-08-24 08:29
edited on: 2018-08-24 08:30

A thought about the abs() changes...

I don't see that anybody gains anything from these changes. Currently with abs(INT_MIN) undefined, applications which call abs(x) for arbitrary integer x must do a pre-call check something like this:
if (x == INT_MIN)
{
   /* special handling ... */
}
else
{
    xmag = abs(x);
}
If the standard changes to require that abs(INT_MIN) returns INT_MIN, this would mean the code could instead do a post-call check something like:
xmag = abs(x);
if (xmag == INT_MIN)
{
   /* special handling ... */
}
but this has no advantage over the pre-call check; in fact the pre-call check is arguably better because it saves a function call.

When we specify behaviour where the C standard says it is undefined, we need a good reason to do so. I see no sufficiently good reason here, and the fact that the change would make some implementations non-conforming is a reason not to make the change.

(0004090)
kre (reporter)
2018-08-24 12:54

Re note 4089

If the standard changes as mentioned, the pre-call check can still be
done if desired (which makes the code C standard conformant) but if
POSIX compliance is all that is needed, then a post-call check can be

xmag = abs(x);
if (xmag < 0)
{
    /* special handling */
}

which turns out to work (on a 2's complement system, ie: anything
POSIX conformant) when abs is a function, or when it is a macro...

#define abs(x) ((x) < 0 ? -(x) : (x))

(and yes, I know that would evaluate its operand twice - the advantage
of the macro is that it is data type agnostic, it works for int, long,
ssize_t, intmax_t, float, double, long double ...)

I don't usually comment on issues like this one, but FWIW, I support the
change - it is perfectly reasonable for any particular implementation to
define what happens for its implementation when a standard says that
something is undefined. That means it is perfectly reasonable for all
implementations, which are POSIX conformant, to define arithmetic as being
what 2's complement produces (without traps for integers, other than
divide by 0) and then if all implementations implement it that way, it
is perfectly reasonable for the POSIX standard to say that is what happens,
so users can rely on it in a more portable way than "just my implementation".

This makes zero difference to anyone writing C standards conformant code,
as if there is any chance that xxx_MIN will be involved in any arithmetic
which could cause undefined C behaviour, the code needs to check before
doing the operation. Hence such code will never do abs(INT_MIN) and what
POSIX says will happen in such a case is irrelevant.

That compiler writers prefer as much to be undefined as possible, so they
can do whatever they like, instead of what is reasonable, doesn't bother me
at all. Let them deal with it.
(0004094)
eblake (manager)
2018-08-30 15:27
edited on: 2018-08-30 15:45

On P280 L9437 (<limits.h>) replace
<CX>Maximum Acceptable Value: −2 147 483 647</CX>
with
<CX>Maximum Acceptable Value: −2 147 483 648</CX>

At Line 9443 replace
Maximum Acceptable Value: −9 223 372 036 854 775 807
with
<CX>Maximum Acceptable Value: −9 223 372 036 854 775 808</CX>

At L9452 replace
Maximum Acceptable Value: −2 147 483 647
with
<CX>Maximum Acceptable Value: −2 147 483 648</CX>

At L9467 replace
Maximum Acceptable Value: −32 767
with
<CX>Maximum Acceptable Value: −32 768</CX>

After P282 L9539 (<limits.h>) add a new paragraph:
The maximum values for SCHAR_MIN, SHRT_MIN, LONG_MIN and LLONG_MIN differ from the C Standard because POSIX.1 requires two's complement representation for the corresponding integer types. The maximum value for INT_MIN differs both for that reason and because POSIX.1 requires that int has a width of at least 32 bits. See also the RATIONALE section for <stdint.h>.

On P282 L9543 (<limits.h>) add <stdint.h> to the SEE ALSO section.

On P348 L11817 (<stdint.h>) change:
An N-bit signed type has values in the range -2<sup>N-1</sup> or 1-2<sup>N-1</sup> to 2<sup>N-1</sup>-1, while an N-bit unsigned type has values in the range 0 to 2<sup>N</sup>-1
with
An N-bit signed type in two's complement representation has values in the range -2<sup>N-1</sup> to 2<sup>N-1</sup>-1, while an N-bit unsigned type has values in the range 0 to 2<sup>N</sup>-1.
<CX>While the C standard also permits signed integers in sign-magnitude or one's complement form, this standard requires an implementation to use two's complement representation for the standard integer types.</CX>

After P349 L11866 add a new paragraph with CX shading:
If the representation of any of the standard types short, int, long or long long is not the same as one of the above required types, an intN_t type with that representation shall be defined along with its uintN_t counterpart.

On P350 L11916 (<stdint.h>) change:
The following type designates a signed integer type capable of representing any value of any signed integer type:
to:
The following type designates a signed integer type <CX>using two's complement representation</CX> capable of representing any value of any signed integer type:

On P351-352 L11944-11965 (<stdint.h>) change all occurrences of:
-1)
to:
)
and add CX shading to the affected text in parentheses.

On P352 L11979 (<stdint.h>), change:
-65 535
to:
<CX>-65 536</CX>

On P354 L12040 (<stdint.h>), replace
(The POSIX standard explicitly requires 8-bit char and two's-complement arithmetic.)
with
Since the POSIX.1 standard explicitly requires 8-bit char with two's complement arithmetic, it is easier for application writers if the same two's complement guarantees are extended to all of the other standard integer types. Furthermore, in programming environments with a 32-bit long, some POSIX.1 interfaces, such as mrand48(), cannot be implemented if long does not use a two's complement representation.

On P567 L19838 (abs), replace
In two's-complement representation, the absolute value of the negative integer with largest magnitude {INT_MIN} might not be representable.
with
Since POSIX.1 requires a two's complement representation of int, the absolute value of the negative integer with the largest magnitude {INT_MIN} is not representable, thus abs(INT_MIN) is undefined.

On P1135 L38361 (imaxabs), replace
The absolute value of the most negative number cannot be represented in two's complement.
with
Since POSIX.1 requires a two's complement representation of intmax_t, the absolute value of the negative integer with the largest magnitude {INTMAX_MIN} is not representable, thus imaxabs(INTMAX_MIN) is undefined.

On P1232 L41195 (labs APPLICATION USAGE), replace
None.
with
Since POSIX.1 requires a two's complement representation of long and long long, the absolute value of the negative integers with the largest magnitude {LONG_MIN} and {LLONG_MIN} are not representable, thus labs(LONG_MIN) and llabs(LLONG_MIN) are undefined.

On P3115 L104217 (printf), replace
twos-complement
with
two's complement



- Issue History
Date Modified Username Field Change
2016-12-09 17:00 nsz New Issue
2016-12-09 17:00 nsz Name => Szabolcs Nagy
2016-12-09 17:00 nsz Organization => musl libc
2016-12-09 17:00 nsz Section => limits.h
2016-12-09 18:40 EdSchouten Note Added: 0003512
2016-12-09 22:25 nsz Note Added: 0003513
2018-06-07 16:10 geoffclare Note Added: 0004041
2018-06-07 16:11 geoffclare Interp Status => ---
2018-06-07 16:11 geoffclare Final Accepted Text => Note: 0004041
2018-06-07 16:11 geoffclare Status New => Resolved
2018-06-07 16:11 geoffclare Resolution Open => Accepted As Marked
2018-06-07 16:11 geoffclare Tag Attached: issue8
2018-07-11 21:10 cmsmith Note Added: 0004050
2018-07-12 08:13 geoffclare Note Added: 0004051
2018-07-12 11:43 shware_systems Note Added: 0004052
2018-07-30 19:02 eblake Note Added: 0004064
2018-07-30 20:29 eblake Relationship added parent of 0001197
2018-08-23 16:32 eblake Resolution Accepted As Marked => Reopened
2018-08-24 08:29 geoffclare Note Added: 0004089
2018-08-24 08:30 geoffclare Note Edited: 0004089
2018-08-24 12:54 kre Note Added: 0004090
2018-08-30 15:27 eblake Note Added: 0004094
2018-08-30 15:40 eblake Note Edited: 0004094
2018-08-30 15:42 eblake Note Edited: 0004094
2018-08-30 15:43 eblake Note Edited: 0004094
2018-08-30 15:44 eblake Note Edited: 0004094
2018-08-30 15:45 eblake Note Edited: 0004094
2018-08-30 15:49 eblake Final Accepted Text Note: 0004041 => Note: 0004094
2018-08-30 15:49 eblake Resolution Reopened => Accepted As Marked
2019-02-14 17:03 eblake Relationship added related to 0001177
2019-02-14 17:07 Don Cragun Relationship replaced has duplicate 0001177
2020-04-23 11:16 geoffclare Status Resolved => Applied


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker