Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[climits.syn] Correct note about types of macros #5926

Merged
merged 3 commits into from Nov 7, 2022

Conversation

Eric41293
Copy link
Contributor

This note was added apparently as a response to LWG 416 (https://cplusplus.github.io/LWG/issue416). However, the submitter of that issue misunderstood the C standard. The required types are not the types that would be produced by an unadorned integer literal, but rather those produced by the integer promotions. Thus, only the macros for (signed|unsigned)? char and (unsigned)? will have a different type. And this is what actual implementations do: https://godbolt.org/z/5E1MojhGh.

Accordingly, the note, as currently written, is at best misleading, because it implies that all the macros may have types that don't match.

This note was added apparently as a response to LWG 416 (https://cplusplus.github.io/LWG/issue416). However, the submitter of that issue misunderstood the C standard. The required types are not the types that would be produced by an unadorned integer literal, but rather those produced by the integer promotions. Thus, only the macros for (signed|unsigned)? char and (unsigned)? will have a different type. And this is what actual implementations do: https://godbolt.org/z/5E1MojhGh.

Accordingly, the note, as currently written, is at best misleading, because it implies that all the macros may have types that don't match.
@jensmaurer
Copy link
Member

What we have is

"The types of the constants defined by macros in \libheader{climits} are not
required to match the types to which the macros refer."

Is that an incorrect summary of the C standard? Do you have a cross reference to the C standard to cross-check that statement?

@Eric41293
Copy link
Contributor Author

ISO C 5.2.4.2.1 states,

"The values given below [of the macros defined by <limits.h>] shall be replaced by constant expressions suitable for use in #if preprocessing directives.

"Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that
have the same type as would an expression that is an object of the corresponding type converted
according to the integer promotions."

ISO C 6.3.1 describes the integer promotions:

"The following may be used in an expression wherever an int or unsigned int may be used:
"— An object or expression with an integer type (other than int or unsigned int) whose integer
conversion rank is less than or equal to the rank of int and unsigned int.
"— A bit-field of type _Bool, int, signed int, or unsigned int.
"If an int can represent all values of the original type (as restricted by the width, for a bit-field), the
value is converted to an int; otherwise, it is converted to an unsigned int. These are called the
integer promotions. All other types are unchanged by the integer promotions."

I consider the current wording to be inaccurate because some of the macros are required to have the same type as the type to which they refer (namely, those referring to int, long, long long, and their unsigned variants).

Copy link
Member

@jwakely jwakely left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the problem statement. Could the suggested new wording be shortened by omitting "that refer to types of integer conversion rank less than that of int"? The statement is true for all of them, it's just that the integer promotions don't change the type for INT_MAX, LONG_MAX etc.

And why isn't MB_LEN_MAX mentioned in your suggested rewording?

@Eric41293
Copy link
Contributor Author

I have removed the reference to conversion rank, but still felt that we need a phrase to explain what types the integral promotions are applied to. I also added MB_LEN_MAX. I had omitted it on the grounds that it does not refer to a type, and so does not need to be explicitly excluded. But I think better of that now.

@jensmaurer
Copy link
Member

I find this wordy. Also, can we make that singular for extra precision?

Suggestion:

Except for ..., a macro referring to an integer type T defines a constant whose type is the promoted type of T (conv.prom).

@tkoeppe
Copy link
Contributor

tkoeppe commented Nov 1, 2022

Looks good -- @jwakely?

Copy link
Member

@jwakely jwakely left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me.

@tkoeppe tkoeppe merged commit 45d9a5b into cplusplus:main Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants