如何生成使用C随机变量名称++使用宏?(How to generate random variabl

2019-06-24 23:50发布

我创建C ++中的宏声明一个变量和一些值分配给它。 根据宏是如何使用的,宏观的第二次出现可以覆盖所述第一变量的值。 例如:

#define MY_MACRO int my_variable_[random-number-here] = getCurrentTime();

其他动机的是使用以避免选择特定名称的变量,以便它是相同的最终通过使用宏开发人员选择一个名称。

有没有一种方法来生成C ++中的宏中随机变量的名字呢?

- 编辑 -

我的意思是独一无二的,但也是随机的,一旦我能在一个块,在这种情况下,它会产生类似于用我的宏两次:

int unique_variable_name;
...
int unique_variable_name;

在这种情况下,是唯一的两个变量名必须是随机生成的。

Answer 1:

加入M4到您的构建流程? 这个宏语言有一些状态的能力,并能成功地与CPP宏混杂。 这可能不是在C环境下生成唯一名称的标准方式,虽然我已经能够以这样的方式成功地使用它。

你可能不不想随机的,顺便说一下,根据你提出你的问题的方式。 你想要独一无二的

您可以使用__FILE____LINE__宏扩展,让你的独特性,你似乎是想为......那些元变量获取源文件的上下文中定义的,所以一定要小心,以确保你得到你所期待的,如(,多个宏的在同一行上危险)。



Answer 2:

尝试以下方法:

// This is some crazy magic that helps produce __BASE__247
// Vanilla interpolation of __BASE__##__LINE__ would produce __BASE____LINE__
// I still can't figure out why it works, but it has to do with macro resolution ordering
#define PP_CAT(a, b) PP_CAT_I(a, b)
#define PP_CAT_I(a, b) PP_CAT_II(~, a ## b)
#define PP_CAT_II(p, res) res

#define UNIQUE_NAME(base) PP_CAT(base, __COUNTER__)

__COUNTER__据传有便携性的问题。 如果是这样,你可以使用__LINE__ ,而不是只要你不是要求比每行或共享跨编译单元的名称一旦宏越多,你会就好了。



Answer 3:

使用__COUNTER__ (作品上gcc4.8,铛3.5和英特尔的icc V13,MSVC 2015年)

#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)
#define uniquename static bool CONCAT(sb_, __COUNTER__) = false


Answer 4:

在预处理器生成唯一的名称是困难的。 你可以得到的最接近的是裂伤__FILE____LINE__到符号作为POPCNT建议。 如果你真的需要生成唯一的全局符号名称,那么我会按照有关使用类似M4或Perl脚本在构建系统,而不是他的建议。

您可能不需要唯一的名称。 如果您的宏可以强加一个新的范围,那么你可以使用相同的名称,因为它只会遮蔽其他定义。 我通常遵循包装宏在共同建议do { ... } while (0)循环。 这仅适用于宏这是一个声明 - 不表达。 宏可以更新使用输出参数变量。 例如:

#define CALC_TIME_SINCE(t0, OUT) do { \
     std::time_t _tNow = std::time(NULL); \
     (OUT) = _tNow - (t0); \
} while (0)

如果你遵循一些规则 ,你通常是很安全:

  1. 使用前导下划线或类似的约定对宏内定义的符号。 这将阻止使用相同的符号,从发生的参数相关的问题。
  2. 仅使用输入参数一次,并始终围绕它们的括号。 这是为了与表达式作为输入宏的工作的唯一办法。
  3. 使用do { ... } while (0)成语,以确保宏仅用作陈述,并避免其他文本替换问题。


Answer 5:

相反,具有预处理程序创建一个名字,你可能让宏用户给你一个名字。

#define MY_MACRO(varname) int varname = getCurrentTime();


Answer 6:

我需要的,我没有任何分析工具的情况下,类似的东西,但我想算多少线程是一个特定的代码块,以及的时间量内(蜱)的代码块花了各线程,在这种情况下每个块需要一个唯一的静态变量所有可访问的线程,我需要后来引用该变量增量(我用了一个日志API,而不是printf的实际代码,但这个工程,以及)。 起初我还以为我是通过以下操作非常巧妙:

#define PROF_START { \
    static volatile int entry_count##___FUNCTION__##__LINE__ = 0; int *ptc = &entry_count##___FUNCTION__##__LINE__; \
    clock_t start, end; \
    start = times(0); \
    (*ptc)++;

但后来我意识到,这仅仅是愚蠢和C编译器将只为你做这个,只要每一个“静态”的声明是自己的块:

#include <stdio.h>
#include <sys/times.h>

#define PROF_START { \
    static int entry_count = 0; \
    clock_t start, end; \
    start = times(0); \
    entry_count++;


#define PROF_END \
    end = times(0); \
    printf("[%s:%d] TIMER: %ld:%d\n" , __FUNCTION__, __LINE__, end-start, entry_count); \
    entry_count--; \
    }

注意每个宏开/关括号。 这不是严格的线程安全的,但我的分析目的,我可以承担增量和DECR操作是原子的。 下面是它采用了宏的递归样本

#define ITEM_COUNT 5

struct node {
   int data;
   struct node *next;
 };

revsort(struct node **head)
{
  struct node *current = *head;
  struct node *next_item;

  while (current->next)
  {
PROF_START
    next_item = current->next;
    current->next = next_item->next;
    next_item->next = *head;
    *head = next_item;
PROF_END
  }
}

rrevsort(struct node **head)
{
  struct node *current = *head;
  struct node *next_item = current->next;

PROF_START
  current->next = 0;
  if (next_item)
  {
   *head = next_item;
    rrevsort(head);
    next_item->next = current;
  }
PROF_END

}

printnode(struct node *head)
{
  if (head)
  {
    printf("%d ", head->data);
    printnode(head->next);
  }
  else
    printf("\n");

}

main()
{

  struct node node_list[ITEM_COUNT];
  struct node *head = &node_list[0];
  int i;

  for (i=0; i < ITEM_COUNT - 1; i++)
  {
PROF_START
      node_list[i].data = i;
      node_list[i].next = &node_list[i+1];
PROF_END
  }
  node_list[i].data = i;
  node_list[i].next = 0;

  printf("before\n");
  printnode(head);
  revsort(&head);
  printf("after\n");
  printnode(head);
  rrevsort(&head);
  printf("before\n");
  printnode(head);
}

额外的提示,上面的程序是一种常见的面试问题。 从“纳米-A”摘录:

macro:0804a034 b entry_count.1715
macro:0804a030 b entry_count.1739
macro:0804a028 b entry_count.1768
macro:0804a02c b entry_count.1775


Answer 7:

这里是一个简洁的宏定义,以产生上述的单例模式。

#define SINGLETON_IMPLIMENTATION(CLASS_NAME) static CLASS_NAME *g##CLASS_NAME = nil; + (CLASS_NAME *)instance { @synchronized(self) { if (g##CLASS_NAME == nil) g##CLASS_NAME = [self new]; } return g##CLASS_NAME; }

#define SINGLETON_DECLARATION(CLASS_NAME) + (CLASS_NAME *)instance;


Answer 8:

虽然我不认为它甚至有可能,你应该认真考虑制定类出于此。

如果你想在一个随机排列的随机元件可以保持一定的值,你可以这样做:

std::vector< std::vector<int> > m_vec;

然后把它包在一个类,因此开发者只能设置一个数字:

void set(int foo)
{
    m_vec[random()][random()] = foo;
}

是否有任何理由,你为什么想要它的宏? 随机变量的名字听起来很危险的,如果它挑选的东西已经在代码中定义别的地方?



文章来源: How to generate random variable names in C++ using macros?