标签: c-preprocessor

字符串化模板参数

在C++中是否可以对模板参数进行字符串化?我试过这个:

#define STRINGIFY(x) #x

template <typename T>
struct Stringify
{
     Stringify()
     {
          cout<<STRINGIFY(T)<<endl;
     }
};

int main() 
{
     Stringify<int> s;
}
Run Code Online (Sandbox Code Playgroud)

但我得到的是'T',而不是'int'.似乎预处理器在模板解析之前启动.

有没有其他方法可以做到这一点?

有没有办法在模板解析后进行预处理?(编译器是VC++).

c++ templates metadata stringification c-preprocessor

34
推荐指数
4
解决办法
2万
查看次数

使用宏"高阶函数"生成器在C中进行函数编程

请注意,因为这是一个问题的地狱;-)

我想在C中使用模板函数进行泛型集合操作(​​如search,foreach等),同时保持编译器静态类型检查.当你使用像这个例子中的简单回调时,这是相当简单的:

#define MAKE_FOREACH(TYPE)\
void foreach_##TYPE (TYPE[n] array, int n, void(*f)(TYPE)) {\
  for(int i = 0; i < n; i++) {\
    f(array[i]);\
  }\
}
Run Code Online (Sandbox Code Playgroud)

所以你可以这样做:

MAKE_FOREACH(int)
MAKE_FOREACH(float)

void intcallback(int x){
  printf("got %d\n", x);
}

void floatcallback(float x){
  printf("got %f\n", x);
}

int main(){
  int[5] iarray = {1,2,3,4,5};
  float[5] farray = {1.0,2.0,3.0,4.0,5.0};
  foreach_int(iarray, 5, intcallback);
  foreach_float(farray, 5, floatcallback);
}
Run Code Online (Sandbox Code Playgroud)

如果我想用返回类型实现回调,例如创建一个"map"函数,我可以这样做:

#define MAKE_MAP(TYPE, RTYPE)\
RTYPE* map_##TYPE (TYPE[n] array, int n, RTYPE(*f)(TYPE)) {\
  RTYPE* result = (RTYPE*)malloc(sizeof(RTYPE)*n);\
  for(int i = 0; i < …
Run Code Online (Sandbox Code Playgroud)

c functional-programming c-preprocessor

33
推荐指数
1
解决办法
5924
查看次数

在C中运行时更改宏

我有一个宏定义.但我需要在运行时根据条件更改此值.我该如何实现呢?

c c-preprocessor

33
推荐指数
4
解决办法
3万
查看次数

宏值的字符串化

我遇到了一个问题 - 我需要使用宏值作为字符串和整数.

 #define RECORDS_PER_PAGE 10

 /*... */

 #define REQUEST_RECORDS \
      "SELECT Fields FROM Table WHERE Conditions" \
      " OFFSET %d * " #RECORDS_PER_PAGE \
      " LIMIT " #RECORDS_PER_PAGE ";"

 char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN];

 /* ...and some more uses of RECORDS_PER_PAGE, elsewhere... */
Run Code Online (Sandbox Code Playgroud)

这失败了一条关于"stray#"的消息,即使它有效,我想我会得到字符串化的宏名称,而不是值.当然,我可以将值提供给最终的方法("LIMIT %d ", page*RECORDS_PER_PAGE),但它既不漂亮也不高效.当我希望预处理器不以特殊方式处理字符串并且像普通代码一样处理它们的内容时,就像这样.就目前而言,我对它进行了解决,#define RECORDS_PER_PAGE_TXT "10"但可以理解的是,我对它并不满意.

怎么做对吗?

c string concatenation c-preprocessor

32
推荐指数
2
解决办法
4万
查看次数

C的常见数组长度宏?

我已经看到了几个浮动数组长度的宏:

这个问题:

  • #define length(array) (sizeof(array)/sizeof(*(array)))
  • #define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
  • #define SIZE(array, type) (sizeof(array) / (sizeof(type))

和Visual Studio的_countof:

#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
Run Code Online (Sandbox Code Playgroud)

我想知道的是:

  1. 那些使用array[0]和有*array什么区别?
  2. 为什么要首选?
  3. 它们在C++方面有区别吗?

c c++ arrays c-preprocessor

32
推荐指数
2
解决办法
3万
查看次数

Variadic宏是非标准的吗?

对于debugbuilds,我通常使用Clang,因为它更好地格式化警告和错误,并使它更容易跟踪它们并修复它们.

但最近在添加了具有可变参数的宏之后,Clang告诉我以下内容(来自虚拟项目):

main.cpp:5:20: warning: named variadic macros are a GNU extension [-Wvariadic-macros]
#define stuff3(args...)  stuff_i(args)
Run Code Online (Sandbox Code Playgroud)

我知道macroname(args...)在各种编译器中编译很好,包括Visualstudio,Sunstudio,当然还有GCC.但是为了确保clang是正确的,我尝试了另外两种扩展可变参数的方法:

1号:

#define stuff1(...)  stuff_i(...)
Run Code Online (Sandbox Code Playgroud)

2号:

#define stuff2(...)  stuff_i(__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

我都收到这条消息:

main.cpp:3:16: warning: variadic macros were introduced in C99 [-Wvariadic-macros]
Run Code Online (Sandbox Code Playgroud)

...这让我想知道Variadic宏是否实际上是C++标准的一部分(当然我知道预处理器是独立解释的)?

c++ c-preprocessor variadic-macros

32
推荐指数
2
解决办法
2万
查看次数

#define中的##是什么意思?

这条线是什么意思?特别是,是什么##意思?

#define ANALYZE(variable, flag)     ((Something.##variable) & (flag))

编辑:

有点困惑.没有结果会是##什么?

c c++ c-preprocessor

32
推荐指数
3
解决办法
2万
查看次数

C预处理器宏是否可以包含预处理程序指令?

我想做相同的以下内容:

#define print_max(TYPE) \
#  ifdef TYPE##_MAX \
     printf("%lld\n", TYPE##_MAX); \
#  endif

print_max(INT);
Run Code Online (Sandbox Code Playgroud)

现在#ifdef,就我在函数宏中看到的那样,不允许使用任何嵌套的预处理程序指令.有任何想法吗?

更新:所以看起来这是不可能的.即使是在运行时检查的黑客也无法实现.所以我想我会选择以下内容:

#ifndef BLAH_MAX
#  define BLAH_MAX 0
#endif
# etc... for each type I'm interested in

#define print_max(TYPE) \
    if (TYPE##_MAX) \
       printf("%lld\n", TYPE##_MAX);

print_max(INT);
print_max(BLAH);
Run Code Online (Sandbox Code Playgroud)

c macros nested expansion c-preprocessor

31
推荐指数
3
解决办法
4万
查看次数

C中的伪泛型

我需要实现一些使用不同数字数组的方法.通常,我会使用泛型来完成这项工作,但由于C不提供它们,我现在正试图使用​​宏来模拟它们.

这是我正在尝试做的一个例子:

#ifndef TYPE
#define TYPE int
#endif

TYPE get_minimum_##TYPE (TYPE * nums, int len){
    TYPE min = nums[0];

    for (int i = 1; i < len; i++) {
        if (nums[i] < min) {
            min = nums[i];
        }
    }

    return min;
}
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译.clang错误消息:

错误:预期';' 在顶级声明者之后

有没有办法在C中这样做?或者我需要手动为每种类型实现这个吗?

c generics c-preprocessor

31
推荐指数
2
解决办法
2万
查看次数

C宏 - 如何将整数值转换为字符串文字

是否可以将#defined 整数符号的值逐字插入到作为GCC(AVR Studio)中汇编部分一部分的字符串文字中?

我希望在下面的asm()块内的字符串文字中将"LEDS"替换为48.

#define LEDS 48 //I only want ONE mention of this number in the source
int x = LEDS;   //I'm using the value directly too

void DrawFrame()
{
    asm(
    "ldi        R27, 0x00       \n\t"
    "ldi        R26, 0x00       \n\t"
    "ldi        R18, LEDS       \n\t" //<-- substitution needed here
...
}
Run Code Online (Sandbox Code Playgroud)

但我希望编译器/汇编程序(在预处理器完成它的工作之后)看到这个......

#define LEDS 48 //I only want ONE mention of this number in the source
int x = LEDS;   //I'm using the value directly too

void DrawFrame()
{
    asm( …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc avr c-preprocessor

31
推荐指数
3
解决办法
4311
查看次数