免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 没本
打印 上一主题 下一主题

C语言带常量参数宏的编译时参数检查,有办法实现吗?(答案已经公开) [复制链接]

论坛徽章:
0
51 [报告]
发表于 2012-02-02 21:17 |只看该作者
本帖最后由 ddddddddd 于 2012-02-02 21:23 编辑

重复

论坛徽章:
0
52 [报告]
发表于 2012-02-02 21:22 |只看该作者
回复 49# OwnWaterloo
>我是在与lz,而不是连这东西都没听说过的你,讨论实现static assert时种种选择权衡。
别,在论坛上是公开发言,别说什么什么是对谁谁谁说的话,就对自己说过的话不负责任了。
也别说什么不愿意搭理啥啥的话,没劲,真的没劲,这种话太老套。
至于“static assert的使用动机”,你有兴趣,我根本就没兴趣,我也没挑起这个话题。我上来针对你的就是那一行“因为c99支持VLA,所以负数下标不顶用了。”。

别玩这种俗套的转移话题好么?


   

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
53 [报告]
发表于 2012-02-02 23:20 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
54 [报告]
发表于 2012-02-03 04:51 |只看该作者
回复 50# gtkmm

至少在i386 windows上,msvc与gcc都要求是2的整数幂,1、2、4、8…… 3不行……
c89,c99没说对齐具体要求,但posix,glibc似乎都认为必须是2的整数幂。
以前看过某个c1x的草稿,貌似准备标准化对齐,不知道最终结果如何……

另外,都是在尽可能从可行的方案中选择对编译器要求低的…… 尽量避免编译器扩展……
比如c1x貌似支持了,c++11也支持。
否则在之前的c89/99,c++03里也有都适用的方案。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
55 [报告]
发表于 2012-02-03 04:58 |只看该作者
回复 53# pmerofc

就是编译时的assert啊,static这个字眼被滥用了……

比如lz提到的检测是否在数组区间内。
假设一些enum被用作下标, chinese,math,english……
static_assert( math < sizeof buf / sizeof *buf );

比如我提到的static_assert(CHAR_BITS==: 只为主流机器编写代码,不支持非8bit字节的机器,但对那种机器可以让编译失败,提早发现问题。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
56 [报告]
发表于 2012-02-03 05:02 |只看该作者
回复 52# ddddddddd

你的质疑我在38楼已经回复过了。
你再问多少次,也是那个回复,我没必要次次都复制给你看。

到底是谁在将话题从我与lz的讨论转移到我对你那不成熟的实现的评价的?
我前面也回复过了,在你让我去看之前,我根本就没看其他楼层的回复。
你这是自我意识过剩?还是自卑?

论坛徽章:
0
57 [报告]
发表于 2012-02-03 12:33 |只看该作者
本帖最后由 gtkmm 于 2012-02-03 12:35 编辑
OwnWaterloo 发表于 2012-02-03 04:51
回复 50# gtkmm

至少在i386 windows上,msvc与gcc都要求是2的整数幂,1、2、4、8…… 3不行……


放心, 不会有支持负数的。 所以
x ?  -1 : 1
是肯定行得通的。

就怕有的编译器, 遇到非法的对齐, 自动忽略, 或是一个warning, 而不是error。。这样assert就失效了。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
58 [报告]
发表于 2012-02-03 16:53 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
59 [报告]
发表于 2012-02-03 17:21 |只看该作者
回复 56# OwnWaterloo
哦,我说得太简略了……

应该这么说:
1. c89/c++中数组的维度是一种提出编译时约束的方法。必须要提供一个编译时常量,否则就是编译错误。
2. 同时也要求这个常量必须>0,对是否可以为0这个细节记不清了,但<0肯定也是错误。 于是就可以用作static assert

但c99里支持VLA,数组维度不需要是编译时常量。
上面的1已经不支持了;所以2这种负数下标的技巧就不顶用了。
-------------------------------
不提什么和别人说话和static_assert了?
那就针对你的38楼,在你的38楼后,我说了一种顶用的“负数下标的技巧”,你还在坚持“负数下标的技巧就不顶用了”?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
60 [报告]
发表于 2012-02-05 18:08 |只看该作者
ddddddddd 发表于 2012-02-03 17:21
不提什么和别人说话和static_assert了? 


我不喜欢将不熟悉的人想象成笨蛋。
讨论是相互补足。而主动地教别人会让我觉得这样是在很傲慢地说:你无知。
其实我自己觉得无知也不是什么大不了的,术业有专攻。但不是所有人都能接受这点……

我觉得既然在我与lz讨论static assert时你来乱入,是明白我是与在讨论什么
但从后面的回帖,我不得不把你当那啥了。

ddddddddd 发表于 2012-02-03 17:21
那就针对你的38楼,在你的38楼后,我说了一种顶用的“负数下标的技巧”,你还在坚持“负数下标的技巧就不顶用了”?


最后给你解释一次,如果还不能理解我也无能为力了。
这东西不懂其实也没啥。 在lz的另一个帖中我也说了在实践中这些技巧不适合复杂的编译时计算。

static assert需要语言提供两方面的机制:
1. 要求某个表达式必须是编译时可求值
2. 编译时的值不满足条件时在编译时报告错误

[exp? 1: -1] 或者 [A*(50-A)] 在c89/c++中是同时满足这两个条件。
但因为c99支持vla,不满足第1个条件,所以这种技巧就不顶用了。
而enum在c与c++各种版本中都满足第1个条件,位域满足两者。

这还只是实现static assert的原理。要让static assert可用,还需要其他一些辅助技巧。
所以又提到了__CONTER__与__LINE__。



另外,容我小人之心一下……
为什么一直要我评论static int arr[A*(50-A)];这种完全不成熟的方案? 这东西你是不是想了很久?不被赞扬一下就不舒服?
但我是不会说这种违心的赞扬的,你等其他人吧……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP