Reputation: 677
My question is the following. I have a large number of static const integers that work as Identifiers. For this reason I would like to know if it is possible to check at compilation time if there is more than one constant with the same value (some kind of static assert...).
I do not want to use an enum as these constants are defined in different modules and I don't want to have like a very long enum with all of them (and some of them are not related to each other).
Here you have a basic example:
// module: foo.h
const uint32_t ELEMENT_TYPE_FOO_X = 46;
const uint32_t ELEMENT_TYPE_FOO_Y = 51;
...
// module: boo.h
const uint32_t ELEMENT_TYPE_BOO_C = 21;
const uint32_t ELEMENT_TYPE_BOO_D = 51;
error: ELEMENT_TYPE_FOO_Y and ELEMENT_TYPE_BOO_D have the same value.
I'm not an expert at all and the only thing that comes to my mind to detect this error is template specialization.
template<uint32_t N>
struct element_traits {
};
template<ELEMENT_TYPE_FOO_X> {
enum { value = ELEMENT_TYPE_FOO };
};
But it seems to be a complex solution. I don't know if there is a more elegant/better solution. I haven't found anything so far.
Thanks in advance.
Upvotes: 3
Views: 317
Reputation: 414179
If large number of constants must be different and must be defined in different source files then you could generate them that way e.g., start with a file that contains filenames and corresponding constant names and generate the rest at each build.
Input file:
[foo.h]
ELEMENT_TYPE_FOO_X
ELEMENT_TYPE_FOO_Y
[boo.h]
ELEMENT_TYPE_BOO_C
ELEMENT_TYPE_BOO_D
The script:
#!/usr/bin/env python
from ConfigParser import SafeConfigParser
from itertools import count
config = SafeConfigParser(allow_no_value=True)
config.optionxform = lambda x: x # use names as-is
config.read('input.cfg')
counter = count(1)
for filename in config.sections():
with open(filename, 'w') as f:
for (name, _), i in zip(config.items(filename), counter):
f.write("const uint32_t %s = %s;\n" % (name, i))
Upvotes: 0
Reputation: 677
Based on Keith's solution. I could "check" constants have unique value for debug build and skip it for release build.
#ifdef DEBUG
#define DEFINE_UNIQUE_CONSTANT(variable, value) \
const uint32_t variable = value; \
uint32_t constant_val_##value = value;
#else
#define DEFINE_UNIQUE_CONSTANT(variable, value) \
const uint32_t variable = value;
#endif
Upvotes: 0
Reputation: 23265
You could certainly do this using macros:
#define UNIQUE_CONSTANT(variable, value) \
const uint32_t variable = value; \
bool constant_val_##value = value;
Then you will get a multiple definition error if the same value is used twice.
(Technically, this will detect the error at link time, not compile time.)
Upvotes: 6