如何在 C++ 中生成随机变量名称 使用宏?
我正在 C++ 中创建一个宏,它声明一个变量并为其分配一些值。 根据宏的使用方式,第二次出现的宏可以覆盖第一个变量的值。 例如:
#define MY_MACRO int my_variable_[random-number-here] = getCurrentTime();
使用它的另一个动机是避免为变量选择特定名称,以便它与开发人员使用宏最终选择的名称相同。
有没有办法在 C++ 宏中生成随机变量名称?
-- 编辑 --
我的意思是唯一的,但也是随机的,一旦我可以在一个块中使用我的宏两次,在这种情况下,它将生成类似的内容:
int unique_variable_name;
...
int unique_variable_name;
在这种情况下,为了唯一,两个变量名称都必须随机生成。
I'm creating a macro in C++ that declares a variable and assigns some value to it. Depending on how the macro is used, the second occurrence of the macro can override the value of the first variable. For instance:
#define MY_MACRO int my_variable_[random-number-here] = getCurrentTime();
The other motivation to use that is to avoid selecting certain name to the variable so that it be the same as a name eventually chosen by the developer using the macro.
Is there a way to generate random variable names inside a macro in C++?
-- Edit --
I mean unique but also random once I can use my macro twice in a block and in this case it will generate something like:
int unique_variable_name;
...
int unique_variable_name;
In this case, to be unique both variable names have to be random generated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
请尝试以下操作:
__COUNTER__
可能存在可移植性问题。 如果这是一个问题,您可以使用__LINE__
代替,只要您每行调用宏的次数不超过一次或在编译单元之间共享名称,就可以了。Try the following:
__COUNTER__
may have portability issues. If this is a problem, you can use__LINE__
instead and as long as you aren't calling the macro more than once per line or sharing the names across compilation units, you will be just fine.使用
__COUNTER__
(适用于 gcc4.8、clang 3.5 和 Intel icc v13、MSVC 2015)use
__COUNTER__
(works on gcc4.8, clang 3.5 and Intel icc v13, MSVC 2015)将 M4 添加到您的构建流程中? 这种宏语言具有一些有状态的功能,并且可以成功地与 CPP 宏混合。 这可能不是在 C 环境中生成唯一名称的标准方法,尽管我已经能够以这种方式成功地使用它。
顺便说一句,根据您提出问题的方式,您可能不希望随机。 您想要独一无二。
您可以在宏扩展中使用 __FILE__ 和 __LINE__ 来获得您想要的唯一性...这些元变量是在源文件上下文中定义的,因此小心确保你得到你正在寻找的东西(例如,同一行上有多个宏的危险)。
Add M4 to your build flow? This macro language has some stateful capabilities, and can successfully be intermingled with CPP macros. This is probably not a standard way to generate unique names in a C environment, though I've been able to sucessfully use it in such a manner.
You probably do not not want random, BTW, based on the way you posed your question. You want unique.
You could use
__FILE__
and__LINE__
in the macro expansion to get you the uniqueness you seem to be going for... those metavariables get defined within the source file context, so be careful to make sure you get what you are looking for (e.g., perils of more than one macro on the same line).在预处理器中生成唯一的名称很困难。 您可以获得的最接近的方法是将
__FILE__
和__LINE__
转换为符号 popcnt 建议。 如果您确实需要生成唯一的全局符号名称,那么我会遵循他的建议,在您的构建系统中使用 M4 或 Perl 脚本之类的东西。您可能不需要唯一的名称。 如果您的宏可以施加新的范围,那么您可以使用相同的名称,因为它只会隐藏其他定义。 我通常遵循将宏包装在
do { ... } while (0)
循环中的常见建议。 这仅适用于作为语句的宏,而不是表达式。 宏可以使用输出参数更新变量。 例如:如果您遵循一些规则,那么您通常非常安全:
do { ... } while (0)
习惯用法可确保宏仅用作语句并避免其他文本替换问题。Generating unique names in the preprocessor is difficult. The closest you can get is to mangle
__FILE__
and__LINE__
into the symbol as popcnt suggests. If you really need to generate unique global symbol names, then I would follow his suggestion about using something like M4 or a Perl script in your build system instead.You might not need unique names. If your macro can impose a new scope, then you can use the same name since it will simply shadow other definitions. I usually follow the common advice of wrapping macros in
do { ... } while (0)
loops. This only works for macros which are statements - not expressions. The macro can update variables using output parameters. For example:If you follow a few rules, you are usually pretty safe:
do { ... } while (0)
idiom to ensure that the macro is only used as a statement and to avoid other textual replacement problems.您可以让宏用户给您一个名称,而不是让预处理器创建名称。
Instead of having the preprocesser create a name, you could possibly let the macro user give you a name.
对于没有任何分析工具的情况,我需要类似的东西,但我想计算特定代码块内有多少线程以及每个线程在该代码块中花费的时间(滴答声)线程,在这种情况下,每个块都需要一个可供所有线程访问的唯一静态变量,并且我需要稍后将该变量引用到 incr (我在实际代码中使用了日志 API 而不是 printf,但这也有效)。 起初我认为我这样做很聪明:
但后来我意识到这很愚蠢,C 编译器会简单地为你做这件事,只要每个“静态”声明都是它自己的块:
注意打开/关闭每个宏中的括号。 这不是严格的线程安全的,但出于分析目的,我可以假设 incr 和 decr 操作是原子的。 这是一个使用宏的递归示例
额外提示,上面的程序是一个常见的面试问题。 摘自“nm-A”:
I needed something similar for a case where I didn't have any profiling tools, but I wanted to count how many threads were inside a particular block of code as well as the amount of time (ticks) spent in that block of code by each thread, In this case every block needed a unique static variable accessible to all threads, and I needed to later reference that variable to incr (I used a logging API rather than printf in the actual code, but this works as well). At first I thought I was very clever by doing the following:
But then I realized this is just silly and the C compiler will simply do this for you, as long as each "static" declaration is its own block:
Note the open/close brackets in each macro. This isn't strictly thread-safe, but for my profiling purposes I could assume the incr and decr operations were atomic. Here's a recursion sample which uses the macros
Extra hint, the above program is a common interview question. Excerpt from "nm -A":
这是一个简洁的宏定义,用于生成上面的单例模式。
Here is a succinct macro definition to generate the singleton pattern above.
虽然我认为这根本不可能,但你应该认真考虑以此为基础开设一门课程。
如果你希望随机数组中的随机元素保存某个值,你可以这样做:
然后将其包装在一个类中,这样开发人员只能设置一个数字:
有什么理由让你想要它是一个宏吗? 随机变量名听起来很危险,如果它选择了代码中其他地方已经定义的东西怎么办?
While I don't think its even possible, you should seriously consider making a class out of this.
If you want a random element in a random array to hold a certain value, you can do this:
Then wrap it in a class, so the developer can only set a number:
Is there any reason why you want it a macro? Random variable name sounds dangerous, what if it picks something already defined somewhere else in the code?