【问题标题】:Evaluate C macro __LINE__ inside another macro在另一个宏中评估 C 宏 __LINE__
【发布时间】:2017-09-09 19:27:41
【问题描述】:

我想创建一个宏,其 __LINE__ 在某个时间点的评估,以便我可以执行以下操作:

#define LINE1 __LINE__
int a[] = {
1,
2,
3
};
#define LINE2 __LINE__
printf("There are %d rows", LINE2 - LINE1 - 2);

...但是LINE2LINE1 最终给了我printf 语句的行号。有什么想法吗?

【问题讨论】:

  • 你能改用const int blah = __LINE__;吗?
  • 你不能那样做。我不确定你能不能做到。 #define LINE1 只是说'当你看到LINE1 时,用__LINE__ 替换它。但是__LINE__ 计算为使用LINE1 的行号,而不是定义它的位置。此外,确定数组中元素数量的正确方法是(sizeof(a) / sizeof(a[0]))——即使有人将两个条目放在一行上,或者在列表中间添加注释等,它也能正常工作。唯一一次当“数组”实际上是函数的指针参数时,它会失败。
  • @HolyBlackCat:这会创建一个变量。 C 没有符号常量。
  • @JonathanLeffler +1 表示注意到,OP 实际上正在尝试做什么

标签: c macros


【解决方案1】:

宏扩展是一个惰性和递归的过程。它很懒,因为当您使用 #define 定义宏时,它不会在您定义它的位置进行评估;相反,它将替换为您使用它的值。并且这种替换将递归地进行,直到它被非宏替换。所以,

printf("There are %d rows", LINE2 - LINE1 - 2);

将扩展为

printf("There are %d rows", __LINE__ - __LINE__ - 2);

依次扩展为

printf("There are %d rows", N - N - 2); // N being the current line number.

您可以按照 HolyBlackCat 的建议更改您的代码。而不是使用#define 声明宏,而是使用const int

const int LINE1 = __LINE__;
   .
   .
   .
const int LINE2 = __LINE__;

【讨论】:

    【解决方案2】:

    愚蠢的黑客:


    #include <stdio.h>
    
    int main(void)
    {
    struct yyy{ char buff[__LINE__ ]; } ;
    #define LINE1 ((int)sizeof(struct yyy))
    int a[] = {
    1,
    2,
    3,
    4
    };
    struct zzz{ char buff[__LINE__ ]; } ;
    #define LINE2 ((int)sizeof(struct zzz))
    printf("[%d,%d]There are %d rows\n", LINE1 , LINE2 , LINE2 - LINE1 - 4);
    
    return 0;
    }
    

    它也适用于文件范围:


    #include <stdio.h>
    
    struct yyy{ char buff[__LINE__ ]; } ;
    #define LINE1 ((int)sizeof(struct yyy))
    int a[] = {
    1,
    2,
    4
    };
    struct zzz{ char buff[__LINE__ ]; } ;
    #define LINE2 ((int)sizeof(struct zzz))
    
    int main(void)
    {
    printf("[%d,%d]There are %d rows\n", LINE1 , LINE2 , LINE2 - LINE1 - 4);
    
    return 0;
    }
    

    注意:这不会创建变量,只会创建两种(未使用的)结构类型。


    还有一个丑陋的技巧:使用枚举(不是对象,而是 constants_in_disguise):


    #include <stdio.h>
    
    enum { OMG=__LINE__ , } ;
    int a[] = {
    #define INDEX(ll) ( (ll)- ((OMG)+3))
    INDEX(__LINE__),
    INDEX(__LINE__),
    INDEX(__LINE__),
    INDEX(__LINE__),
    INDEX(__LINE__),
    INDEX(__LINE__)
    };
    enum { WTF=__LINE__ , } ;
    
    int main(void)
    {
    printf("[%d,%d]There are %d rows\n", OMG , WTF , WTF - OMG - 4);
    
    return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-12
      • 2019-12-17
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      相关资源
      最近更新 更多