使用无符号数据类型强制执行非负值和/或有效值是最佳做法吗? [英] Is it a best practice to use unsigned data types to enforce non-negative and/or valid values?
问题描述
最近,在重构会话期间,我正在查找一些我写的代码,并注意到几个事情:
Recently, during a refactoring session, I was looking over some code I wrote and noticed several things:
-
unsigned char
以强制在区间[0-255]中的值。 - 使用的其他函数
int
或
或
数据类型与
if
c>上限但不包含在 已知且确定的非负数下限
被声明为unsigned
数据类型(int根据可能性,
上限或
已超过4,000,000,000)。
- I had functions that used
unsigned char
to enforce values in the interval [0-255]. - Other functions used
int
orlong
data types withif
statements inside the functions to silently clamp the values to valid ranges. - Values contained in classes and/or declared as arguments to functions that had an unknown
upper bound
but a known and definite non-negativelower bound
were declared as anunsigned
data type (int
orlong
depending on the possibility that theupper bound
went above 4,000,000,000).
不一致性令人不安。这是一个好的做法,我应该继续吗?我应该重新思考逻辑,坚持使用 int
或 long
和适当的非通知钳位?
The inconsistency is unnerving. Is this a good practice that I should continue? Should I rethink the logic and stick to using int
or long
with appropriate non-notifying clamping?
有关使用适当的注意事项:有些情况下我使用签名的
数据类型,并在值出现时抛出通知异常超出范围,但这些保留为 divde由零
和构造函数
。
A note on the use of "appropriate": There are cases where I use signed
data types and throw notifying exceptions when the values go out of range but these are reserved for divde by zero
and constructors
.
推荐答案
我可能会认为一致性是最重要的。如果你选择一种方式,做正确的,那么它会很容易让别人明白你在做什么在以后的时间点。
I would probably argue that consistency is most important. If you pick one way and do it right then it will be easy for someone else to understand what you are doing at a later point in time. On the note of doing it right, there are several issues to think about.
首先,在检查整数变量n是否在有效范围内时,常见的是: 0至N写入:
First, it is common when checking if an integer variable n is in a valid range, say 0 to N to write:
if ( n > 0 && n <= N ) ...
这种比较只有在n被签名时才有意义。如果n是无符号的,那么它永远不会小于0,因为负值将环绕。你可以重写上面的如果只是:
This comparison only makes sense if n is signed. If n is unsigned then it will never be less than 0 since negative values will wrap around. You could rewrite the above if as just:
if ( n <= N ) ...
如果有人不习惯看到这个,他们可能会感到困惑,认为你做错了。
If someone isn't used to seeing this, they might be confused and think you did it wrong.
其次,我要记住,不能保证c ++中的整数的类型大小。因此,如果你想要的东西被限制255,一个unsigned char可能不会做的伎俩。如果变量有一个特定的含义,那么它可能是有价值的一个typedef显示。例如,size_t是与存储器地址一样宽的值。这意味着你可以使用它与数组,而不必担心在32或64位的机器。我尽量使用这样的typedefs尽可能的,因为他们清楚地沟通我为什么使用的类型。 (size_t,因为我正在访问数组。)
Second, I would keep in mind that there is no guarantee of type size for integers in c++. Thus, if you want something to be bounded by 255, an unsigned char may not do the trick. If the variable has a specific meaning then it may be valuable to to a typedef to show that. For example, size_t is a value as wide as a memory address. Which means that you can use it with arrays and not have to worry about being on 32 or 64 bit machines. I try to use such typedefs whenever possible because they clearly communicate why I am using the type. (size_t because I'm accessing an array.)
第三,回到关于环绕的问题。您想使用无效的号码发生什么。在unsigned char的情况下,如果使用类型来绑定数据,那么您将无法检查是否输入了超过255的值。这可能是也可能不是问题。
Third, is back on the issue of wrap around. What do you want to happen with an invalid number. In the case of an unsigned char, if you use the type to bound the data, then you won't be able to check if a value over 255 was entered. That may or may not be a problem.
这篇关于使用无符号数据类型强制执行非负值和/或有效值是最佳做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!