你能使增量编译器保持常量吗?

时间:2010-03-31 22:44:34

标签: c

听起来毫无意义......

我想要一个常数,每次使用时它都会增加1

int x;
int y;
x = INCREMENTING_CONSTANT;
y = INCREMENTING_CONSTANT;

其中x == 1;和y == 2

注意我不想要y = INCREMENTING_CONSTANT + 1类型的解决方案。

基本上我想将它用作编译时唯一ID(通常它不会在代码中使用,例如在另一个宏中)

9 个答案:

答案 0 :(得分:8)

这不是标准,但有些编译器支持 __COUNTER__ 宏。见Has anyone ever had a use for the __COUNTER__ pre-processor macro?

答案 1 :(得分:7)

您可以使用Boost.Preprocessor(与C一起使用)和BOOST_PP_COUNTER

将某些内容组合在一起

docs页面上给出的示例:

#include <boost/preprocessor/slot/counter.hpp>   
BOOST_PP_COUNTER // 0

#include BOOST_PP_UPDATE_COUNTER()   
BOOST_PP_COUNTER // 1

#include BOOST_PP_UPDATE_COUNTER()  
BOOST_PP_COUNTER // 2

#include BOOST_PP_UPDATE_COUNTER()
BOOST_PP_COUNTER // 3

翻译成你想要的东西

#include <boost/preprocessor/slot/counter.hpp> 

int x = BOOST_PP_COUNTER; // 0

#include BOOST_PP_UPDATE_COUNTER()   
int y = BOOST_PP_COUNTER;// 1

#include BOOST_PP_UPDATE_COUNTER()  
int z = BOOST_PP_COUNTER; // 2

你也可以使用插槽(比上述解决方案更多的代码可以使用更多的代码):

#include <boost/preprocessor/slot/slot.hpp>

#define BOOST_PP_VALUE 0 //ensure 0 to start
#include BOOST_PP_ASSIGN_SLOT(1) 
int a = BOOST_PP_SLOT(1); //0

#define BOOST_PP_VALUE 1 + BOOST_PP_SLOT(1)
#include BOOST_PP_ASSIGN_SLOT(1) 
int b = BOOST_PP_SLOT(1); //1

答案 2 :(得分:7)

如果您只需要一些独特的ID ish ,您可以使用__LINE__预处理器符号吗?这不是你要求的,但它可能适合你的目的。

答案 3 :(得分:2)

在我的情况下,我希望每个子系统都有一个系统范围的唯一密钥,但子系统的选择取决于使用系统的人。这些需要是8位值,因为它针对的是嵌入式系统。

这就是我刚才提出的:

#define LAST_KEY -1

// SUB1_KEY definition
enum {
  SUB1_KEY_ORIGIN = LAST_KEY,
  SUB1_KEY,
};
#undef LAST_KEY
#define LAST_KEY SUB1_KEY

// SUB2_KEY definition
enum {
  SUB2_KEY_ORIGIN = LAST_KEY,
  SUB2_KEY,
};
#undef LAST_KEY
#define LAST_KEY SUB2_KEY

// SUB3_KEY definition
enum {
  SUB3_KEY_ORIGIN = LAST_KEY,
  SUB3_KEY,
};
#undef LAST_KEY
#define LAST_KEY SUB3_KEY

// ....

挑战在于确保每次引入每个块的包含链都以相同的顺序编译。

答案 4 :(得分:1)

我经常希望编译时变量。但是,最简单的方法就是为每个常量定义常量。

如果您使用C而不是C ++,可以通过在某些全局状态类或类似解决方案中使用functionoid来解决上面我的线程问题的答案。

您也可以尝试使用xmacro。创建一个新文件,我们称之为xmacro.h

INCREMENTING_CONSTANT;
#define INCREMENTING_CONSTANT INCREMENTING_CONSTANT + 1

然后,在标准标题中,

#define INCREMENTING_CONSTANT 0
#define USE_INCREMENTING_CONSTANT #include "xmacro.h"

const int x = USE_INCREMENTING_CONSTANT

我没有对此进行过测试,但xmacros有一些常规宏无法使用的强大功能,比如defs / undefs,而我的直觉说它应该可行。预处理器功能强大,但相当愚蠢,因此可能会失败。

答案 5 :(得分:0)

您希望xy本身是常量吗?如果是这样,最简单和最干净的事情可能是使用匿名枚举:

enum {
    x = 1,
    y
    /* Add new ones here. */
};

这意味着您只需要为该列表添加一个新名称,它将被赋予下一个整数值。这是一个有用的技巧,你不关心值是什么(运行时之外),只要它们是不同的。例如,在为GUI中的控件分配标识符时,您经常会看到:

enum {
    button1_id = FIRST_USER_ID,
    button2_id,
    combo_id,
    ...
}

某些GUI框架提供了一个GetUserId()函数,它将生成一个新函数(使用内部静态变量);但我认为这发生在运行时。看到连续多次打电话也是有点乏味的。

button1_id = GetUserId();
button2_id = GetUserId();
combo_id = GetUserId();
...

答案 6 :(得分:-2)

嗯,那不是常数,不是吗? ;)

您可以使用以下功能执行此操作:

int id() {
  static int i = 0;
  return ++i;
}

x = id();
y = id();

如图所示,这不是线程安全的。为此,您需要使用互斥锁来保护它,或使用编译器/平台特定的原子增量器。

答案 7 :(得分:-3)

“递增常数”是矛盾的。你不能在编译时这样做。

答案 8 :(得分:-5)

这是一种实施它的丑陋方式。

static int _counter=0;
#define INCREMENTING_CONSTANT (_counter++)