免费注册 查看新帖 |

Chinaunix

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

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

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

你有没有看lz的第2种实现里第22行?
还是说你目的就不是来讨论这个主题的,仅仅是来搅和的?

论坛徽章:
0
42 [报告]
发表于 2012-02-01 19:29 |只看该作者
本帖最后由 ddddddddd 于 2012-02-01 19:29 编辑
OwnWaterloo 发表于 2012-02-01 19:27
回复 40# ddddddddd

你有没有看lz的第2种实现里第22行?

当然看了,怎么了?那你看没看我给出的答案呢?
>0是可用的

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

>> 其中参数A使用时必为常量,且在0..50范围内。那么如何在编译时判断越界并报错停止编译,而不是在运行时?
>>         int i=0;
>>         M(i);

第2种实现无法检测出这种设计之外的使用,已经无法在编译时检测是否合法。

我解释其原因是因为c99支持VLA,VLA使得数组维度不再是一个编译时常量约束。
对22行这种使用非编译时值,连检测其是否<0的前提条件都没有了。
所以这种技巧不顶用了。

除了一开始说得太简略了,还有什么问题?

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

先前我只看了lz的帖,是说static assert的。
这东西我很早就充分了解了,所以就只针对lz回复了一下,楼下的就没看。还有其他贴等着我回呢……

刚才看了,你的回复完全没上道嘛……

论坛徽章:
0
45 [报告]
发表于 2012-02-01 19:59 |只看该作者
OwnWaterloo 发表于 2012-02-01 19:54
回复 42# ddddddddd

先前我只看了lz的帖,是说static assert的。

static int arr[A*(50-A)];
你的意思是解决不了问题?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
46 [报告]
发表于 2012-02-01 20:15 |只看该作者
本帖最后由 OwnWaterloo 于 2012-02-01 20:27 编辑

回复 45# ddddddddd

问题有很多:

1. 为嘛要加static ……
不一定能被优化掉
而typedef 完全是编译时的东西,保证没有运行时开销

2. 有可能会出现未使用变量之类的警告
但没见过有编译器会说:未使用typedef的警告

3. 错误使用,也就是22行。
我就是在解释是因为VLA的关系才无法检测出错误使用的情况。


此外,这都还只是在选择通过何种方式提出编译时检测。还有其他一些问题,比如名字。

我一开始的回复简化一下就是:
1. 数组维度、enum、位域都可以用于提出编译时常量这一约束,但前者在c99中不行
2. 报告错误的方式有数组维度、位域不能为负
3. 避免重名用标准的__LINE__就够了,不需要__COUNTER__扩展

论坛徽章:
0
47 [报告]
发表于 2012-02-01 20:28 |只看该作者
为嘛要加static
加和不加是有大区别的,至于优化,那就不用担心了,未用变量加不加static都一样。
出现警告的问题……这咋说呢,用c的人,谁在乎警告?

论坛徽章:
0
48 [报告]
发表于 2012-02-02 10:41 |只看该作者
回复 46# OwnWaterloo
你应该看一下你第一次发言:因为c99支持VLA,所以负数下标不顶用了。
“因为c99支持VLA”就“所以负数下标不顶用了”?那是lz的方法不顶用,而不是“负数下标不顶用”了。
自己都不知道别人针对你的那句话发言么?

又提出名字的问题,你的意思是名字可能会重复的问题吧,在你提出这个问题的时候能不能想想这到底是不是问题?
把自己当评委了吧



   

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

哦,我真没想到这句话对你来说思维跨度大到我解释补充后你依然不懂。
我是在与lz,而不是连这东西都没听说过的你,讨论实现static assert时种种选择权衡。
你连static assert的使用动机都不明白,能虚心点么? 说白了,根本就不太愿意搭理你。
等你哪天自己实现过这个东西,也许能明白我说的意思。 不过按你这种东一枪西一炮,到处插嘴的讨论风格,我真觉得你是上来解闷而已的。

论坛徽章:
0
50 [报告]
发表于 2012-02-02 21:15 |只看该作者
本帖最后由 gtkmm 于 2012-02-02 21:19 编辑
OwnWaterloo 发表于 2012-02-02 17:51
回复 48# ddddddddd

哦,我真没想到这句话对你来说思维跨度大到我解释补充后你依然不懂。


其实还有一个办法的, 就是对齐。
编译器不应该允许负数对齐。
(再强大的CPU, 可以对齐3字节, 也不应该对齐到负数上。。。)

eg.  gcc:

#define static_check(x)   ({struct __attribute__((aligned(x?1:-1)))  {}_;})


int main(){
   static_check(-1);
   static_check(2);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP