此相关问题是关于在编译时确定签名类型的最大值:
但是,我已经意识到在运行时确定有符号类型(例如time_t或off_t)的最大值似乎是一项非常困难的任务.
我能想到的最接近解决方案的是:
uintmax_t x = (uintmax_t)1<<CHAR_BIT*sizeof(type)-2;
while ((type)x<=0) x>>=1;
Run Code Online (Sandbox Code Playgroud)
只要type没有填充位,这就避免了任何循环,但是如果type确实有填充位,则强制转换会调用实现定义的行为,这可能是信号或无意义的实现定义转换(例如,剥离符号位).
在我看来,我开始认为问题是无法解决的,这有点令人不安,并且会成为C标准的缺陷.证明我错的任何想法?
更新:值得庆幸的是,我之前的回答是错误的,这个问题似乎有一个解决方案。
intmax_t x;
for (x=INTMAX_MAX; (T)x!=x; x/=2);
Run Code Online (Sandbox Code Playgroud)
该程序要么产生x包含 type 的最大可能值T,要么生成实现定义的信号。
解决信号情况可能是可能的,但很困难并且在计算上不可行(例如必须为每个可能的信号号安装信号处理程序),所以我认为这个答案并不完全令人满意。POSIX 信号语义可能会提供足够的附加属性以使其可行;我不知道。
(T)x有趣的部分是,当导致实现定义的转换时会发生什么,特别是如果您愿意假设您没有使用将生成信号的实现。上述循环的技巧在于它根本不依赖于实现对转换值的选择。它所依赖的(T)x==x只是当且仅当x适合 type 时才可能T,否则 的值将超出type的任何表达式x的可能值范围。T
老想法,错误的,因为它没有考虑上述(T)x==x属性:
我想我有一个草图证明我正在寻找的东西是不可能的:
INT_MAX>32767。INT_MAX定义一个与 X 相同的新 C 实现 Y,但其中和的值INT_MIN均除以 2。该大纲的基本思想是,由于与带符号类型的越界值相关的所有内容都是实现定义或未定义的行为,因此可以考虑带符号整数类型的任意数量的高值位作为填充位,除了 中的限制宏之外,实际上没有对实现进行任何更改limits.h。
你有什么想法这听起来是正确的还是虚假的?如果它是正确的,我很乐意将赏金奖励给那些能够最好地使其更加严格的人。
| 归档时间: |
|
| 查看次数: |
5156 次 |
| 最近记录: |