我想创建一个宏,其值是某个点__LINE__
的评估,以便我可以执行以下操作:
#define LINE1 __LINE__
int a[] = {
1,
2,
3
};
#define LINE2 __LINE__
printf("There are %d rows", LINE2 - LINE1 - 2);
...但LINE2
和LINE1
最终会给我printf
声明的行号。有什么想法吗?
答案 0 :(得分:3)
宏扩展是一个懒惰的递归过程。它是懒惰的,因为当您使用#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__;
答案 1 :(得分:1)
愚蠢的黑客:
#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;
}