Discussion:
unsigned char and short promotions rationale?
(too old to reply)
p***@gmail.com
2018-09-20 07:20:52 UTC
Permalink
Hello,

I would like to find out the reason of the following entry in the cpp
standard regarding Integral promotions:

4.5 Integral promotions
1. A prvalue of an integer type other than bool, char16_t, char32_t, or
wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be converted to a prvalue
of type int if int can represent all
the values of the source type; otherwise, the source prvalue can be
converted to a prvalue of type unsigned
int.
this means that unsigned char and unsigned short are something that gets
promoted to int on common platforms.
And this is not a lucky thing. What can happen is following code:

unsigned short a = 1;
unsigned short b=2;
std::cout << ~(a<<b) << std::endl; // and here we get negative value
this way we end up having an negative value, while we are operating only on
unsigned types, which is IMO bad.
Example of such behavior compiled and running: running example
<https://ideone.com/MmmSCL>

The question is:

Is this some legacy, that came to C++ from C language?
Is there any possibility to improve that, so that unsigned types can get
promoted to the unsigned types first?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Thiago Macieira
2018-09-21 04:11:03 UTC
Permalink
Post by p***@gmail.com
Is this some legacy, that came to C++ from C language?
Yes. It's legacy from pre-C too, when machines didn't deal well with types of
sizes other than their register width, though relatively recent machines like
Alpha still had restrictions that need to be taken care of.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned types can get
promoted to the unsigned types first?
No, I don't think so. First of all, you'd need to convince WG14 and I don't
think they'll go for it. Second, changing this behaviour means that anyone who
currently has correct code that depends on this behaviour and promotion to int
would suddenly get unsigneds.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Dawid Pilarski
2018-09-21 05:31:49 UTC
Permalink
Hello, thanks for response.

I might be wrong, but in case of C anytime you are actually using an
integer you need to say explicitly
how to interpret it. There is no automatic type deduction, so it should not
change behavior of many programs.
I guess this is why they didn't care that much about unsigned being
promoted to signed, because in the end
you still have to say explicitly how to interpret the variable.

The only exception from above would be a chain of integer operations like
(~(a << b)) >> c; (which in this case might already be implementation
defined behavior) that can have it's result changed,
but I might be missing something else.

At the same time it's hard for me to believe, that this feature can be used
correctly in C++. I would assume
that if such feature is used, the users are not aware of it and most
probably are using it incorrectly.

I will try to reach the WG14 guys and maybe organize some statistics if
needed.

Hopefully we can make things simpler...
Post by Thiago Macieira
Post by p***@gmail.com
Is this some legacy, that came to C++ from C language?
Yes. It's legacy from pre-C too, when machines didn't deal well with types of
sizes other than their register width, though relatively recent machines like
Alpha still had restrictions that need to be taken care of.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned types can get
promoted to the unsigned types first?
No, I don't think so. First of all, you'd need to convince WG14 and I don't
think they'll go for it. Second, changing this behaviour means that anyone who
currently has correct code that depends on this behaviour and promotion to int
would suddenly get unsigneds.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
David Brown
2018-09-21 06:49:15 UTC
Permalink
Post by p***@gmail.com
Hello,
I would like to find out the reason of the following entry in the cpp
4.5 Integral promotions
1. A prvalue of an integer type other than bool, char16_t, char32_t,
or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be converted to a
prvalue of type int if int can represent all
the values of the source type; otherwise, the source prvalue can
be converted to a prvalue of type unsigned
int.
this means that unsigned char and unsigned short are something that gets
promoted to int on common platforms.
unsigned short a = 1;
unsigned short b=2;
std::cout << ~(a<<b) << std::endl; // and here we get negative value
this way we end up having an negative value, while we are operating only
on unsigned types, which is IMO bad.
Example of such behavior compiled and running: running example
<https://ideone.com/MmmSCL>
Is this some legacy, that came to C++ from C language?
Yes, it came to C++ from C. Prior to C standardisation, there were some
compilers that preserved signedness during promotion (i.e., unsigned
short promoted to unsigned int), and others that preserved only value
(i.e., unsigned short promoted to int).

There are good reasons for each of the systems.

You have given an example where promotion to signed int gives an
unexpected or unwanted result.

But if promotion were to unsigned int, then the expression "a - 5 > 0"
would give an unexpected and unwanted result.

There is no way to choose a method that is /always/ what you want, or
always what makes sense.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned types can get
promoted to the unsigned types first?
No - changing it would break far too much existing code in subtle ways.

(My own opinion is that signedness preserving promotion would have been
a better choice. But that is based on the C and C++ we write today, the
code we have today, and the compilers we have today. When this decision
was made, the C world was "everything's an int" and the "promote to int
where possible" rule was the best choice at the time.)

Anyway, this is C++. Make your own set of signed and unsigned integer
classes and choose how to promote them :-)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Dawid Pilarski
2018-09-21 07:05:46 UTC
Permalink
@David Brown, thanks for response,

yes, indeed I think you are right, that writing own types with own set of
rules is most probably a better choice, than changing the standard and
possibly breaking
the code.

Thanks!
Post by David Brown
Post by p***@gmail.com
Hello,
I would like to find out the reason of the following entry in the cpp
4.5 Integral promotions
1. A prvalue of an integer type other than bool, char16_t, char32_t,
or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be converted to a
prvalue of type int if int can represent all
the values of the source type; otherwise, the source prvalue can
be converted to a prvalue of type unsigned
int.
this means that unsigned char and unsigned short are something that gets
promoted to int on common platforms.
unsigned short a = 1;
unsigned short b=2;
std::cout << ~(a<<b) << std::endl; // and here we get negative value
this way we end up having an negative value, while we are operating only
on unsigned types, which is IMO bad.
Example of such behavior compiled and running: running example
<https://ideone.com/MmmSCL>
Is this some legacy, that came to C++ from C language?
Yes, it came to C++ from C. Prior to C standardisation, there were some
compilers that preserved signedness during promotion (i.e., unsigned
short promoted to unsigned int), and others that preserved only value
(i.e., unsigned short promoted to int).
There are good reasons for each of the systems.
You have given an example where promotion to signed int gives an
unexpected or unwanted result.
But if promotion were to unsigned int, then the expression "a - 5 > 0"
would give an unexpected and unwanted result.
There is no way to choose a method that is /always/ what you want, or
always what makes sense.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned types can get
promoted to the unsigned types first?
No - changing it would break far too much existing code in subtle ways.
(My own opinion is that signedness preserving promotion would have been
a better choice. But that is based on the C and C++ we write today, the
code we have today, and the compilers we have today. When this decision
was made, the C world was "everything's an int" and the "promote to int
where possible" rule was the best choice at the time.)
Anyway, this is C++. Make your own set of signed and unsigned integer
classes and choose how to promote them :-)
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
David Brown
2018-09-21 07:27:35 UTC
Permalink
Usually, of course, a simple cast or a temporary variable of the
specific type is going to be less effort than making your own types:

unsigned short a = 1;
unsigned short b = 2;
std::count << ~((unsigned) a << b) << std::endl;

You can call it inelegant, but it's a good deal simpler than your own
integer class library!

David
Post by Dawid Pilarski
@David Brown, thanks for response,
yes, indeed I think you are right, that writing own types with own set
of rules is most probably a better choice, than changing the standard
and possibly breaking
the code.
Thanks!
Post by p***@gmail.com
Hello,
I would like to find out the reason of the following entry in the cpp
4.5 Integral promotions
1. A prvalue of an integer type other than bool, char16_t,
char32_t,
Post by p***@gmail.com
or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be converted to a
prvalue of type int if int can represent all
the values of the source type; otherwise, the source
prvalue can
Post by p***@gmail.com
be converted to a prvalue of type unsigned
int.
this means that unsigned char and unsigned short are something
that gets
Post by p***@gmail.com
promoted to int on common platforms.
unsigned short a = 1;
unsigned short b=2;
std::cout << ~(a<<b) << std::endl; // and here we get negative
value
Post by p***@gmail.com
this way we end up having an negative value, while we are
operating only
Post by p***@gmail.com
on unsigned types, which is IMO bad.
Example of such behavior compiled and running: running example
<https://ideone.com/MmmSCL>
Is this some legacy, that came to C++ from C language?
Yes, it came to C++ from C. Prior to C standardisation, there were some
compilers that preserved signedness during promotion (i.e., unsigned
short promoted to unsigned int), and others that preserved only value
(i.e., unsigned short promoted to int).
There are good reasons for each of the systems.
You have given an example where promotion to signed int gives an
unexpected or unwanted result.
But if promotion were to unsigned int, then the expression "a - 5 > 0"
would give an unexpected and unwanted result.
There is no way to choose a method that is /always/ what you want, or
always what makes sense.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned types
can get
Post by p***@gmail.com
promoted to the unsigned types first?
No - changing it would break far too much existing code in subtle ways.
(My own opinion is that signedness preserving promotion would have been
a better choice. But that is based on the C and C++ we write today, the
code we have today, and the compilers we have today. When this decision
was made, the C world was "everything's an int" and the "promote to int
where possible" rule was the best choice at the time.)
Anyway, this is C++. Make your own set of signed and unsigned integer
classes and choose how to promote them :-)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Dawid Pilarski
2018-09-21 08:23:38 UTC
Permalink
Surely it is, but the thing is, that you need to remember each time, that
promotion happens and need to react.

In big projects the mistakes like that are unavoidable.

In fact, the reason I started the thread is that I meat such issue in a
project after running some static code analysis tools ;)
Post by David Brown
Usually, of course, a simple cast or a temporary variable of the
unsigned short a = 1;
unsigned short b = 2;
std::count << ~((unsigned) a << b) << std::endl;
You can call it inelegant, but it's a good deal simpler than your own
integer class library!
David
Post by Dawid Pilarski
@David Brown, thanks for response,
yes, indeed I think you are right, that writing own types with own set
of rules is most probably a better choice, than changing the standard
and possibly breaking
the code.
Thanks!
Post by p***@gmail.com
Hello,
I would like to find out the reason of the following entry in the
cpp
Post by Dawid Pilarski
Post by p***@gmail.com
4.5 Integral promotions
1. A prvalue of an integer type other than bool, char16_t,
char32_t,
Post by p***@gmail.com
or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be converted
to a
Post by Dawid Pilarski
Post by p***@gmail.com
prvalue of type int if int can represent all
the values of the source type; otherwise, the source
prvalue can
Post by p***@gmail.com
be converted to a prvalue of type unsigned
int.
this means that unsigned char and unsigned short are something
that gets
Post by p***@gmail.com
promoted to int on common platforms.
unsigned short a = 1;
unsigned short b=2;
std::cout << ~(a<<b) << std::endl; // and here we get negative
value
Post by p***@gmail.com
this way we end up having an negative value, while we are
operating only
Post by p***@gmail.com
on unsigned types, which is IMO bad.
Example of such behavior compiled and running: running example
<https://ideone.com/MmmSCL>
Is this some legacy, that came to C++ from C language?
Yes, it came to C++ from C. Prior to C standardisation, there were
some
Post by Dawid Pilarski
compilers that preserved signedness during promotion (i.e., unsigned
short promoted to unsigned int), and others that preserved only value
(i.e., unsigned short promoted to int).
There are good reasons for each of the systems.
You have given an example where promotion to signed int gives an
unexpected or unwanted result.
But if promotion were to unsigned int, then the expression "a - 5 >
0"
Post by Dawid Pilarski
would give an unexpected and unwanted result.
There is no way to choose a method that is /always/ what you want, or
always what makes sense.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned types
can get
Post by p***@gmail.com
promoted to the unsigned types first?
No - changing it would break far too much existing code in subtle
ways.
Post by Dawid Pilarski
(My own opinion is that signedness preserving promotion would have
been
Post by Dawid Pilarski
a better choice. But that is based on the C and C++ we write today,
the
Post by Dawid Pilarski
code we have today, and the compilers we have today. When this
decision
Post by Dawid Pilarski
was made, the C world was "everything's an int" and the "promote to
int
Post by Dawid Pilarski
where possible" rule was the best choice at the time.)
Anyway, this is C++. Make your own set of signed and unsigned
integer
Post by Dawid Pilarski
classes and choose how to promote them :-)
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
David Brown
2018-09-21 09:20:19 UTC
Permalink
Post by Dawid Pilarski
Surely it is, but the thing is, that you need to remember each time,
that promotion happens and need to react.
It is rare in practice that you need to do anything. C has been around
for 40 years or so, and C++ for half that, using these rules. You do
need to know the rules for integer promotion, but for the most part the
defaults are fine.

If you have cases where there are problems, then using your own classes
is definitely a possible solution. It is likely that "strong typing"
classes would be even better. (I.e., instead of storing the number of
wotsits in your own Uint16_t class that does not promote to int, store
it in a WotsitCount class.)
Post by Dawid Pilarski
In big projects the mistakes like that are unavoidable.
They are absolutely avoidable - make sure people working on the project
know the language. There are many things in C++ that are hard - this is
not one of them.

And one of the things you use in large projects to help avoid problems
is static analysis tools. (Compiler warnings are often enough here.)
Post by Dawid Pilarski
In fact, the reason I started the thread is that I meat such issue in a
project after running some static code analysis tools ;)
Your static analysis tools are doing exactly what you want them to do -
spotting possible errors.

(Your written English is excellent - but if I may point it out, you made
an amusing mistake. "meet" means "encounter" or "come across", while
"meat" is the type of food. Spell checkers can't help much with that
kind of bug.)

mvh.,

David
Post by Dawid Pilarski
Usually, of course, a simple cast or a temporary variable of the
unsigned short a = 1;
unsigned short b = 2;
std::count << ~((unsigned) a << b) << std::endl;
You can call it inelegant, but it's a good deal simpler than your own
integer class library!
David
Post by Dawid Pilarski
@David Brown, thanks for response,
yes, indeed I think you are right, that writing own types with own set
of rules is most probably a better choice, than changing the standard
and possibly breaking
the code.
Thanks!
Post by p***@gmail.com
Hello,
I would like to find out the reason of the following entry
in the cpp
Post by Dawid Pilarski
Post by p***@gmail.com
4.5 Integral promotions
1. A prvalue of an integer type other than bool, char16_t,
char32_t,
Post by p***@gmail.com
or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be
converted to a
Post by Dawid Pilarski
Post by p***@gmail.com
prvalue of type int if int can represent all
the values of the source type; otherwise, the source
prvalue can
Post by p***@gmail.com
be converted to a prvalue of type unsigned
int.
this means that unsigned char and unsigned short are something
that gets
Post by p***@gmail.com
promoted to int on common platforms.
And this is not a lucky thing. What can happen is following
unsigned short a = 1;
unsigned short b=2;
std::cout << ~(a<<b) << std::endl; // and here we get
negative
Post by Dawid Pilarski
value
Post by p***@gmail.com
this way we end up having an negative value, while we are
operating only
Post by p***@gmail.com
on unsigned types, which is IMO bad.
Example of such behavior compiled and running: running example
<https://ideone.com/MmmSCL>
Is this some legacy, that came to C++ from C language?
Yes, it came to C++ from C. Prior to C standardisation, there
were some
Post by Dawid Pilarski
compilers that preserved signedness during promotion (i.e.,
unsigned
Post by Dawid Pilarski
short promoted to unsigned int), and others that preserved
only value
Post by Dawid Pilarski
(i.e., unsigned short promoted to int).
There are good reasons for each of the systems.
You have given an example where promotion to signed int gives an
unexpected or unwanted result.
But if promotion were to unsigned int, then the expression "a
- 5 > 0"
Post by Dawid Pilarski
would give an unexpected and unwanted result.
There is no way to choose a method that is /always/ what you
want, or
Post by Dawid Pilarski
always what makes sense.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned types
can get
Post by p***@gmail.com
promoted to the unsigned types first?
No - changing it would break far too much existing code in
subtle ways.
Post by Dawid Pilarski
(My own opinion is that signedness preserving promotion would
have been
Post by Dawid Pilarski
a better choice. But that is based on the C and C++ we write
today, the
Post by Dawid Pilarski
code we have today, and the compilers we have today. When
this decision
Post by Dawid Pilarski
was made, the C world was "everything's an int" and the
"promote to int
Post by Dawid Pilarski
where possible" rule was the best choice at the time.)
Anyway, this is C++. Make your own set of signed and unsigned
integer
Post by Dawid Pilarski
classes and choose how to promote them :-)
--
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Dawid Pilarski
2018-09-21 12:09:55 UTC
Permalink
haha, indeed ;p thanks for spotting this. I am aware of the difference. I
did the mistake by accident.

I also get your point about static code analysis and compiler warnings.
On the other hand I would like to make the language itself as simple and
safe as possible.

And yes, there are harder things than this one in the C++, but this one has
potential of being easily skipped IMO.

Nonetheless, I am not going to do anything about the issue itself as not
much can be done here. I will try to write
library to help with that issue and check it's performance and ease of use.

Thank you all a lot for assistance :)

Best regards,
Dawid
Post by David Brown
Post by Dawid Pilarski
Surely it is, but the thing is, that you need to remember each time,
that promotion happens and need to react.
It is rare in practice that you need to do anything. C has been around
for 40 years or so, and C++ for half that, using these rules. You do
need to know the rules for integer promotion, but for the most part the
defaults are fine.
If you have cases where there are problems, then using your own classes
is definitely a possible solution. It is likely that "strong typing"
classes would be even better. (I.e., instead of storing the number of
wotsits in your own Uint16_t class that does not promote to int, store
it in a WotsitCount class.)
Post by Dawid Pilarski
In big projects the mistakes like that are unavoidable.
They are absolutely avoidable - make sure people working on the project
know the language. There are many things in C++ that are hard - this is
not one of them.
And one of the things you use in large projects to help avoid problems
is static analysis tools. (Compiler warnings are often enough here.)
Post by Dawid Pilarski
In fact, the reason I started the thread is that I meat such issue in a
project after running some static code analysis tools ;)
Your static analysis tools are doing exactly what you want them to do -
spotting possible errors.
(Your written English is excellent - but if I may point it out, you made
an amusing mistake. "meet" means "encounter" or "come across", while
"meat" is the type of food. Spell checkers can't help much with that
kind of bug.)
mvh.,
David
Post by Dawid Pilarski
Usually, of course, a simple cast or a temporary variable of the
unsigned short a = 1;
unsigned short b = 2;
std::count << ~((unsigned) a << b) << std::endl;
You can call it inelegant, but it's a good deal simpler than your own
integer class library!
David
Post by Dawid Pilarski
@David Brown, thanks for response,
yes, indeed I think you are right, that writing own types with own
set
Post by Dawid Pilarski
Post by Dawid Pilarski
of rules is most probably a better choice, than changing the
standard
Post by Dawid Pilarski
Post by Dawid Pilarski
and possibly breaking
the code.
Thanks!
Post by p***@gmail.com
Hello,
I would like to find out the reason of the following entry
in the cpp
Post by Dawid Pilarski
Post by p***@gmail.com
4.5 Integral promotions
1. A prvalue of an integer type other than bool,
char16_t,
Post by Dawid Pilarski
Post by Dawid Pilarski
char32_t,
Post by p***@gmail.com
or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be
converted to a
Post by Dawid Pilarski
Post by p***@gmail.com
prvalue of type int if int can represent all
the values of the source type; otherwise, the source
prvalue can
Post by p***@gmail.com
be converted to a prvalue of type unsigned
int.
this means that unsigned char and unsigned short are
something
Post by Dawid Pilarski
Post by Dawid Pilarski
that gets
Post by p***@gmail.com
promoted to int on common platforms.
And this is not a lucky thing. What can happen is following
unsigned short a = 1;
unsigned short b=2;
std::cout << ~(a<<b) << std::endl; // and here we get
negative
Post by Dawid Pilarski
value
Post by p***@gmail.com
this way we end up having an negative value, while we are
operating only
Post by p***@gmail.com
on unsigned types, which is IMO bad.
Example of such behavior compiled and running: running
example
Post by Dawid Pilarski
Post by Dawid Pilarski
Post by p***@gmail.com
<https://ideone.com/MmmSCL>
Is this some legacy, that came to C++ from C language?
Yes, it came to C++ from C. Prior to C standardisation, there
were some
Post by Dawid Pilarski
compilers that preserved signedness during promotion (i.e.,
unsigned
Post by Dawid Pilarski
short promoted to unsigned int), and others that preserved
only value
Post by Dawid Pilarski
(i.e., unsigned short promoted to int).
There are good reasons for each of the systems.
You have given an example where promotion to signed int gives
an
Post by Dawid Pilarski
Post by Dawid Pilarski
unexpected or unwanted result.
But if promotion were to unsigned int, then the expression "a
- 5 > 0"
Post by Dawid Pilarski
would give an unexpected and unwanted result.
There is no way to choose a method that is /always/ what you
want, or
Post by Dawid Pilarski
always what makes sense.
Post by p***@gmail.com
Is there any possibility to improve that, so that unsigned
types
Post by Dawid Pilarski
Post by Dawid Pilarski
can get
Post by p***@gmail.com
promoted to the unsigned types first?
No - changing it would break far too much existing code in
subtle ways.
Post by Dawid Pilarski
(My own opinion is that signedness preserving promotion would
have been
Post by Dawid Pilarski
a better choice. But that is based on the C and C++ we write
today, the
Post by Dawid Pilarski
code we have today, and the compilers we have today. When
this decision
Post by Dawid Pilarski
was made, the C world was "everything's an int" and the
"promote to int
Post by Dawid Pilarski
where possible" rule was the best choice at the time.)
Anyway, this is C++. Make your own set of signed and unsigned
integer
Post by Dawid Pilarski
classes and choose how to promote them :-)
--
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Myriachan
2018-09-25 20:20:20 UTC
Permalink
Post by David Brown
Post by Dawid Pilarski
In big projects the mistakes like that are unavoidable.
They are absolutely avoidable - make sure people working on the project
know the language. There are many things in C++ that are hard - this is
not one of them.
How many modern C/C++ programmers would realize that this is undefined
behavior (on most modern architectures)?

std::uint16_t x = 65535u;
x *= x;

It's way too late to change these rules. I'd much rather that signed
integer overflow be well-defined to deal with the problem instead.

As it is, I have to do stuff like this to create my own types that are
similar to uint_fastX_t, lest I subtly introduce undefined behavior in my
cryptography code:

typedef decltype(std::uint16_t() + 0u) uint_prom16_t;
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
David Brown
2018-09-26 07:28:55 UTC
Permalink
Post by David Brown
Post by Dawid Pilarski
In big projects the mistakes like that are unavoidable.
They are absolutely avoidable - make sure people working on the project
know the language. There are many things in C++ that are hard - this is
not one of them.
How many modern C/C++ programmers would realize that this is undefined
behavior (on most modern architectures)?
std::uint16_t x = 65535u;
x *= x;
This one is certainly a counter-intuitive oddity - no disagreements
there. But /no/ selection of promotion rules would let you avoid all
unexpected promotions. The promotion rules of C (and therefore C++)
were picked in order to minimise the likelihood of getting confusing
results - not to eliminate the possibility. It doesn't matter what
promotion rules you pick, or what oeverflow behaviour you pick, it will
always be possible to write sensible-looking code that does not do what
you think.

There are three ways to deal with this. You can learn exactly how C
works for promotions, conversions and overflows. You can actively add
casts or temporary variables to force particular behaviour. Or you can
write enough C++ classes that you can explicitly choose the behaviour
you want at the time you want it.

For C, I'd recommend a mix of the first two. Learn the common rules,
and any time there is something unusual or which you suspect might vary
by implementation or be unclear to some readers, put in the casts or
temporary variables manually. You can do the same in C++, but you could
also be a little more creative (such as making a Uint16_t that can be
implicitly converted to "unsigned int", but not to "int").
Post by David Brown
It's way too late to change these rules. I'd much rather that signed
integer overflow be well-defined to deal with the problem instead.
As it is, I have to do stuff like this to create my own types that are
similar to uint_fastX_t, lest I subtly introduce undefined behavior in
typedef decltype(std::uint16_t() + 0u) uint_prom16_t;
Surely that is the same as "unsigned int" ? I can't even think of any
hypothetical cases where it would be anything different.

(I am fully in agreement with being explicit about your types,
promotions and conversions in code such as cryptography. It is common
practice in my field of small embedded systems programming, especially
as resource constraints mean it is not uncommon to have data in
smaller-than-int sizes.)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Continue reading on narkive:
Loading...