同时实施它的参数宏在EX pression使用时必须编译时间常数 [英] Macro for use in expression while enforcing its arguments to be compile time constants

查看:145
本文介绍了同时实施它的参数宏在EX pression使用时必须编译时间常数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要寻找一种方式来#定义强制执行它的参数是编译时间常数的宏,并在同一时间可在离pression使用。该方法应该是C90下工作,是向上兼容 - 如有可能,还为便携式不同的C ++的变种。另外一个0足迹内存是preferable。

I am looking for a way to #define a macro that enforces its arguments to be compile time constants, and at the same time can be used in an expression. The method should be working under C90 and be upward compatible - if possible also portable for the different C++ variants. Also a 0-footprint to memory is preferable.

考虑一个编译时的最低宏作为一个例子。行为应该是:

Consider a compile-time minimum macro as an example. The behavior should be:

 #define CT_MIN(CTC_A, CTC B) <<<MAGIC>>>

 int a = 1;
 int b = a + CT_MIN(1,4); /* OK */
 int c = a + CT_MIN(a,4); /* COMPILER DIAGNOSTIC */

要挑起编译诊断,一般我可以效仿的静态断言的东西,如:

To provoke an compile diagnostic, in general I could emulate a static assert with something like:

 typedef char ct_check_is_ct_constant[(CTC_A != 0) + 1];

这不会编译(或将提出一些在诊断至少),如果不是编译时间常数(数)用于CTC_A任何其他;但如果CTC_A是一个数字,它永远是成功的(给予一定的照顾范围)。
但这种断言只会多语句宏内工作,所以不可能作为前pression的一部分来使用。

which wouldn't compile (or will raise some diagnostic at least) if anything other than a compile time constant (number) is used for CTC_A; but if CTC_A is an number, it will always be successful (given some care with scopes). But this assert would only work within a multi-statement macro and so would not be possible to use as part of an expression.

我猜,事中的行:

  #define CT_MIN(CTC_A, CTC_B)                   \
         ( <expr check CTC_A>,                   \
           <expr check CTC_B>,                   \
           (CTC_A) < (CTC_B))? (CTC_A) : (CTC_B) \
         )

但我不知道前任pressions必须看起来怎么样,如果这样的事情存在。

But I have no idea how the expressions must look like, and if such thing exists.

任何想法?

背景:

我必须通过一个costumized头一个巨大的没有太多可靠的消息来源常量量。这些常量强烈参数化我的code。我想要实现preprocessor期间零足迹检查和编译时间,该常数,同时检查我的假设,环境,和我的技能写一个正确的code发生器。

I have a huge amount of constants from not too much reliable sources via an costumized header. These constants strongly parametrize my code. I want to implement a zero footprint checks during preprocessor and compile time for this constants, to check both my assumptions, the environment, and my skills to write a correct code generator.

推荐答案

您可以使用的sizeof 应用于匿名结构与单一类型的字段是局部定义的枚举,其值必须是整型常量前pressions:

You can use sizeof applied to an anonymous struct with a single field whose type is a locally defined enum whose values must be constant integer expressions:

#define CT_MIN(CTC_A, CTC_B)                                               \
    ( sizeof(struct { enum { must_be_constant_expression = CTC_A } x; }),  \
      sizeof(struct { enum { must_be_constant_expression = CTC_B } x; }),  \
      (CTC_A) < (CTC_B) ? (CTC_A) : (CTC_B)                                )

由铛产生的错误信息是非常明确的:

The error messages produced by clang is very explicit:

enumassert.c:32:24: error: expression is not an integer constant expression
    int c = a + CT_MIN(a,4); /* COMPILER DIAGNOSTIC */
                       ^
enumassert.c:17:60: note: expanded from macro 'CT_MIN'
    ( sizeof(struct { enum { must_be_constant_expression = CTC_A } x; }),  \
                                                           ^

此溶液似乎没有任何符号添加到名字空间。此外,如果你需要处理非整数类型,在略低于precise错误信息的成本,你可以添加一个铸像这样:

This solution does not seem to add any symbol to the name space. Furthermore, if you need to handle non integer types, at the cost of a slightly less precise error message, you can add a cast like this:

#define CT_MIN(CTC_A, CTC_B)                                               \
    ( sizeof(struct { enum { must_be_constant_expression = (int)(CTC_A) } x; }),  \
      sizeof(struct { enum { must_be_constant_expression = (int)(CTC_B) } x; }),  \
      (CTC_A) < (CTC_B) ? (CTC_A) : (CTC_B)                                )

这篇关于同时实施它的参数宏在EX pression使用时必须编译时间常数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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