size_t(SIZE_MAX)的最大值是否相对于其他整数类型定义? [英] Is the max value of size_t (SIZE_MAX) defined relative to the other integer types?

查看:485
本文介绍了size_t(SIZE_MAX)的最大值是否相对于其他整数类型定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个函数库,可以安全地在各种数字类型之间进行转换或者尝试。
我的意图大致等于创建有用库和学习C边缘情况。

I'm writing a library of functions that will safely convert between various numeric types or die trying. My intent is roughly equal parts create-useful-library and learn-C-edge-cases.

我的 int -to - size_t 函数触发GCC -Wtype-limits 警告声称我不应该测试 int 是否大于 SIZE_MAX ,因为它永远不会成立。
(另一个将 int 转换为 ssize_t 的函数会产生一个关于 SSIZE_MAX的相同警告。)

My int-to-size_t function is triggering a GCC -Wtype-limits warning that claims I shouldn't test if an int is greater than SIZE_MAX, because it will never be true. (Another function that converts int to ssize_t produces an identical warning about SSIZE_MAX.)

我的MCVE,附加评论和小步骤,是:

My MCVE, with extra comments and baby steps, is:

#include <stdint.h>  /* SIZE_MAX */
#include <stdlib.h>  /* exit EXIT_FAILURE size_t */

extern size_t i2st(int value) {
    if (value < 0) {
        exit(EXIT_FAILURE);
    }
    // Safe to cast --- not too small.
    unsigned int const u_value = (unsigned int) value;
    if (u_value > SIZE_MAX) {  /* Line 10 */
        exit(EXIT_FAILURE);
    }
    // Safe to cast --- not too big.
    return (size_t) u_value;
}



编译器警告



<我在Linux 2.6.34上收到GCC 4.4.5的类似警告:

The Compiler Warnings

I'm getting similar warnings from GCC 4.4.5 on Linux 2.6.34:

$ gcc -std=c99 -pedantic -Wall -Wextra -c -o math_utils.o math_utils.c

math_utils.c: In function ‘i2st’:
math_utils.c:10: warning: comparison is always false due to limited range of data type

...以及GCC 4.8 .5在Linux 3.10.0上:

...and also from GCC 4.8.5 on Linux 3.10.0:

math_utils.c: In function ‘i2st’:
math_utils.c:10:5: warning: comparison is always false due to limited range of data type [-Wtype-limits]
     if (u_value > SIZE_MAX) {  /* Line 10 */
     ^

这些警告对我来说似乎不合理,至少在一般情况下是这样。
(我不否认某些特定硬件和编译器组合的比较可能是
总是假
。)

These warnings don't appear justified to me, at least not in the general case. (I don't deny that the comparison might be "always false" on some particular combination of hardware and compiler.)

C 1999标准似乎不排除 int 大于 SIZE_MAX

The C 1999 standard does not appear to rule out an int being greater than SIZE_MAX.

部分
6.5.3.4 sizeof 运算符
根本不会解决 size_t ,除非将其描述为
中定义< stddef .h> (和其他标题)。

Section "6.5.3.4 The sizeof operator" doesn't address size_t at all, except to describe it as "defined in <stddef.h> (and other headers)".

部分
7.17通用定义< stddef .h>
size_t 定义为
sizeof 运算符。
(谢谢,伙计们!)

Section "7.17 Common definitions <stddef.h>" defines size_t as "the unsigned integer type of the result of the sizeof operator". (Thanks, guys!)

部分
7.18.3其他整数类型的限制
更有帮助---
它将
限制 size_t 定义为:


SIZE_MAX 65535

...含义 SIZE_MAX 可以 small 为65535.
int
(有符号或无符号)
可能比这大得多,具体取决于硬件和编译器。

...meaning SIZE_MAX could be as small as 65535. An int (signed or unsigned) could be much greater than that, depending on the hardware and compiler.

接受
的回答 unsigned int vs. size_t
似乎支持我的解释
(强调增加):

The accepted answer to "unsigned int vs. size_t" seems to support my interpretation (emphasis added):


size_t 类型可能大于,等于,或小于 unsigned int ,您的编译器可能会对其进行假设以进行优化。

The size_t type may be bigger than, equal to, or smaller than an unsigned int, and your compiler might make assumptions about it for optimization.

这个答案引用了与我已经引用的C标准相同的
第7.17节

This answer cites the same "Section 7.17" of the C standard that I've already quoted.

我的搜索结果显示Open Group的论文
数据大小中立性和64位支持
索赔
64位数据模型
(重点补充):

My searches turned up the Open Group's paper "Data Size Neutrality and 64-bit Support", which claims under "64-bit Data Models" (emphasis added):


ISO / IEC 9899:1990,编程语言 - C(ISO C)
留下了<$ c $的定义c> short int , int long int 指针故意模糊
[...]
唯一的限制是 int s必须不小比 s, long s必须不小于 int s, size_t 必须代表实现支持的最大无符号类型
[...]
基本数据类型之间的关系可表示为:

ISO/IEC 9899:1990, Programming Languages - C (ISO C) left the definition of the short int, the int, the long int, and the pointer deliberately vague [...] The only constraints were that ints must be no smaller than shorts, and longs must be no smaller than ints, and size_t must represent the largest unsigned type supported by an implementation. [...] The relationship between the fundamental data types can be expressed as:


sizeof(char)< = sizeof(短)< = sizeof(int)< = sizeof(长) = sizeof(size_t)

sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) = sizeof(size_t)


如果这是真的,那么测试 int 对抗 SIZE_MAX 确实是徒劳的......
但本文并未引用章节和经文,所以我无法分辨其作者是如何达成的他们的结论。
他们自己的
基本规范版本7
sys / types.h docs
不会解决这个问题。

If this is true, then testing an int against SIZE_MAX is indeed futile... but this paper doesn't cite chapter-and-verse, so I can't tell how its authors reached their conclusion. Their own "Base Specification Version 7" sys/types.h docs don't address this either way.

我知道 size_t 不太可能比更窄int ,但 C标准保证比较 some_unsigned_int> SIZE_MAX 总是是假的吗?
如果是这样,在哪里?

I understand that size_t is unlikely to be narrower than an int, but does the C standard guarantee that comparing some_unsigned_int > SIZE_MAX will always be false? If so, where?

这有两个半重复问题,但他们都在询问关于 size_t 应该代表什么以及何时应该/不应该使用的更多一般性问题。

There are two semi-duplicates of this question, but they are both asking more general questions about what size_t is supposed to represent and when it should / should-not be used.


  • 什么是 size_t 在C?
    没有解决 size_t 与其他整数类型之间的关系。
    其接受的答案只是维基百科的一句话,它没有提供我已经找到的任何信息。

  • "What is size_t in C?" does not address the relationship between size_t and the other integer types. Its accepted answer is just a quote from Wikipedia, which doesn't provide any information beyond what I've already found.

size_t 的正确定义是什么?
几乎开始了重复我的问题,但然后转向偏离,当应该使用 size_t 以及为何引入它时询问

它作为上一个问题的副本被关闭。

"What is the correct definition of size_t?" starts off nearly a duplicate of my question, but then veers off course, asking when size_t should be used and why it was introduced. It was closed as a duplicate of the previous question.

推荐答案

当前的C标准不要求 size_t 至少与 int 一样宽,而且我是对任何版本的标准持怀疑态度。 size_t 需要能够表示任何可能是对象大小的数字;如果实现将对象大小限制为24位宽,则 size_t 可以是24位无符号类型,无论 int 是。

The current C standard does not require size_t to be at least as wide as an int, and I'm skeptical about any version of the standard ever doing so. size_t needs to be able to represent any number which might be the size of an object; if the implementation limits object sizes to be 24 bits wide, then size_t could be a 24-bit unsigned type, regardless of what an int is.

GCC警告并未提及理论上的可能性。它正在检查特定的硬件平台以及特定的编译器和运行时。这意味着它有时会触发试图可移植的代码。 (在其他情况下,可移植代码将触发可选的GCC警告。)这可能不是您希望警告可以做的,但可能有用户的期望与实现的行为完全匹配,并且标准不提供任何指导对于编译器警告。

The GCC warning does not refer to theoretical possibilities. It is checking a particular hardware platform and a particular compiler and runtime. That means it sometimes triggers on code which is trying to be portable. (There are other cases where portable code will trigger optional GCC warnings.) That might not be what you were hoping the warning would do, but there are probably users whose expectations are precisely matched by the implemented behaviour, and the standard provides no guidelines whatsoever for compiler warnings.

正如OP在评论中提到的那样,这个警告有很长的历史记录。警告是在版本3.3.2左右(2003年)中引入的,显然不受任何 -W 标志的控制。这被用户明显感觉为错误12963 。你这样做,警告不鼓励便携式编程。从错误报告中可以看出,各种GCC维护者(以及社区中其他知名成员)都强烈感受到了相互冲突的意见。 (这是开源错误报告中常见的动态。)几年后,决定使用标志来控制警告,并且默认情况下不启用该标志或作为 -Wall <的一部分启用/ code>。与此同时, -W 选项已重命名为 -Wextra ,以及新创建的标志( -Wtype-limits )已添加到 -Wextra 集合中。对我而言,这似乎是正确的解决方案。

As OP mentions in a comment, there is a long history related to this warning. The warning was introduced in version 3.3.2 or so (in 2003), apparently not controlled by any -W flag. This was reported as bug 12963 by a user who evidently felt, as you do, that the warning discourages portable programming. As can be seen in the bug report, various GCC maintainers (and other well-known members of the community) weighed in with strongly-felt but conflicting opinions. (This is a common dynamic in open source bug reports.) After several years, the decision was made to control the warnings with a flag, and to not enable that flag by default or as part of -Wall. In the meantime, the -W option had been renamed -Wextra, and the newly-created flag (-Wtype-limits) was added to the -Wextra collection. To me, this appears to be the correct resolution.

本答复的其余部分包含了我个人的观点。

-Wall ,如GCC手册中所述,实际上并未启用 all 警告。它使那些警告关于一些用户认为有问题的构造,并且易于避免(或修改以防止警告),甚至与宏结合使用。 GCC可以检测到许多其他条件:

-Wall, as documented in the GCC manual, does not actually enable all warnings. It enables those warnings "about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros." There are a number of other conditions which GCC can detect:


请注意,并未暗示某些警告标志 - 华尔街。他们中的一些人警告用户通常不认为有问题的结构,但有时你可能希望检查;其他人警告在某些情况下必要或难以避免的构造,并且没有简单的方法来修改代码以抑制警告。其中一些是由 -Wextra 启用的,但其中许多必须单独启用。

Note that some warning flags are not implied by -Wall. Some of them warn about constructions that users generally do not consider questionable, but which occasionally you might wish to check for; others warn about constructions that are necessary or hard to avoid in some cases, and there is no simple way to modify the code to suppress the warning. Some of them are enabled by -Wextra but many of them must be enabled individually.

这些区别有点武断。例如,每次GCC决定在'|''内建议围绕'&&'括号时,我都要咬紧牙关。 (似乎没有必要在'+'中围绕'*'建议括号,这对我来说并没有什么不同。)但我认识到我们所有人都有不同的舒适度与运算符优先级,而不是全部海湾合作委员会关于括号的建议对我来说似乎过分。

These distinctions are somewhat arbitrary. For example, I have to grit my teeth every time that GCC decides to "suggest parentheses around ‘&&’ within ‘||’". (It doesn't seem to feel the need to suggest parentheses around ´*´ within ´+´, which doesn't feel different to me.) But I recognize that all of us have different comfort levels with operator precedence, and not all of GCC's suggestions about parentheses seem excessive to me.

但总的来说,这种区别似乎是合理的。有一些通常适用的警告,并且使用 -Wall 启用这些警告,应该总是指定,因为这些警告几乎总是要求操作纠正缺陷。还有其他警告可能在特定情况下有用,但也有很多误报;这些警告需要单独调查,因为它们并不总是(甚至经常)与代码中的问题相对应。

But on the whole, the distinction seems reasonable. There are warnings which are generally applicable, and those are enabled with -Wall, which should always be specified because these warnings almost always demand action to correct a deficiency. There are other warnings which might be useful in particular circumstances, but which also have lots of false positive; these warnings need to be investigated individually because they do not always (or even often) correspond with a problem in your code.

我知道有些人会感觉到GCC知道如何警告某些情况这一事实足以要求采取行动以避免这种警告。每个人都有权获得他们的风格和审美判断,这是正确的,只是这样的程序员将 -Wextra 添加到他们的构建标志中。然而,我并不在那群人中。在项目的给定点,我将尝试使用大量可选警告启用的构建,并考虑是否根据报告修改我的代码,但我真的不想花费我的开发时间每次重建文件时都要考虑非问题。 -Wtypes-limit 标志对我来说属于这个类别。

I'm aware that there are people who feel that the mere fact that GCC knows how to warn about some condition is sufficient to demand action to avoid that warning. Everyone is entitled to their stylistic and aesthetic judgements, and it is right and just that such programmers add -Wextra to their build flags. I am not in that crowd, however. At a given point in a project, I will try a build with a large collection of optional warnings enabled, and consider whether or not to modify my code on the basis of the reports, but I really don't want to spend my development time thinking about non-problems every time I rebuild a file. The -Wtypes-limit flag falls into this category for me.

这篇关于size_t(SIZE_MAX)的最大值是否相对于其他整数类型定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆