【问题标题】:C Macro to remove duplicates in list of argumentsC宏删除参数列表中的重复项
【发布时间】:2012-12-12 09:46:08
【问题描述】:

我想知道是否可以构建一个 gnu C 宏,该宏扩展为一个标记列表(整数),这些标记是宏的参数,没有重复。可以假设参数的数量是固定的(目前)。 IE。我想要类似的东西:

#define MAC(a,b,c) ???

扩展例如

MAC(1,2,1)

1,2。 参数没有排序,结果也不必排序。


根据下面的建议,我构建了一个示例,它基本上可以使用 p99 完成我想要的功能,包括:

#include <p99/p99_if.h>
#include <p99/p99_paste.h>

#define MAC2(a,b) double P99_PASTE2(myvar_, a) P99_IF_EQ(a,b)()(; double P99_PASTE2(myvar_, b))
#define MAC3(a,b,c) double P99_PASTE2(myvar_, a) P99_IF_EQ(a,b)()(; double P99_PASTE2(myvar_, b)) P99_IF_EQ(a,c)()(P99_IF_EQ(b,c)()(; double P99_PASTE2(myvar_, c)) )

MAC2(1,2);
MAC2(3,3);

MAC3(1,2,3);
MAC3(10,10,1);

【问题讨论】:

  • 很难想象为什么你宁愿写MAC(1,2,1)而不是简单地写1,2
  • 诚然,应用并不明显。我想定义一组取决于索引(MAC 的参数)的变量。但是这三个指数过度确定了变量。只需要部分信息。当然,我可以手动减少索引列表,但是如果我出错,这会导致代码不一致。
  • 为什么不写一个看起来像int * unique_list(int*, int )void remove_duplicates(int *, int)的函数
  • @UmNyobe:表达式需要在编译前扩展,因为它应该确定变量名。

标签: c macros p99


【解决方案1】:

如果您的参数总是像示例中的小十进制数字,您可以摆脱我在P99 中提供的内容。它有像 P99_IF_EQ 这样的宏,你可以用作

#define MAC(A,B) unsigned P99_PASTE2(myvar_, A) P99_IF_EQ(A,B)()(; unsigned P99(unsigned P99_PASTE2(myvar_, B))

MAC(1,2); // -> myvar_1 and myvar_2
MAC(3,3); // -> myvar_3

仅在不等于 A 时扩展 B 的声明。显然,对于三个不同的论点,这已经变得有点乏味了,但还是可行的。

【讨论】:

  • 我决定试一试。它具有我可以使用的不同功能。我用 gcc 下载并成功编译了测试示例。奇怪的是icc -I /usr/local/include/p99 -Wall -c -o test-p99-double -std=c99 test-p99-double.c(版本 13.0.1)我得到:/usr/local/include/p99/p99_block.h(473): error: expected a ";" void p00_longjmp(p00_jmp_buf0 * p00_buf, int p00_val) { ^ test-p99-double.c(56): warning #12: parsing restarts here after previous syntax error P99_IS_GT(1, 1); 等等。我做错了什么?
  • 这缺少一个右圆括号。我修改了您的答案以考虑三个指数,请参阅我修改后的问题。不幸的是,我仍然无法让它与 icc 一起使用。预处理器生成无法编译的代码。
  • 我发现它在省略#line指令时用icc编译:icc -I /usr/local/include -std=c99 -P -o test test.c
  • @highsciguy,AFAIR icc 在 C99 上有问题。而且由于它不是免费的,我并不总是有可供测试的版本。您能否通过其他渠道向我发送详细报告和/或补丁?谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-09-12
  • 2017-10-12
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 1970-01-01
相关资源
最近更新 更多