实现一个字符串的编译时间检查机制的独特性 [英] Implementing compile-time mechanism checking uniqueness of a string

查看:144
本文介绍了实现一个字符串的编译时间检查机制的独特性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

定义我的问题的最简单的方法是,我试图实现一种机制,将检查是否相同的字符串已经使用(或一对(数字,字符串))。我想用C preprocessor一个聪明的方式来实现这种机制。我也想,这个机制给了我编译错误时有冲突或运行时在调试模式下的错误(通过检查断言)。我们不希望开发者加入消息时,因为每个消息应该是唯一犯了一个错误。我知道,它可以通过计算散列或例如完成的 CRC / MD5 但是这个机制将是冲突的脆弱,我需要避免的。至关重要的是,所有的消息只能使用一次。

The simplest way of defining my problem is that I'm trying to implement a mechanism that would check whether the same string had already been used (or a pair (number, string)). I would like this mechanism to be implemented in a smart way using C preprocessor. I would also like that this mechanism gave me compile errors when there is a conflict or run-time errors in Debug mode (by checking assertions). We don't want the developer to make a mistake when adding a message, as every message should be unique. I know that it could be done by calculating a hash or for example crc/md5 but this mechanism would be conflict-vulnerable which I need to avoid. It is crucial that every message can be used only once.

这种机制的例子行为:

addMessage(1, "Message1") //OK 
addMessage(2, "Message2") //OK 
. 
. 
. 
addMessage(N, "MessageN") //OK 
addMessage(2, "Message2") //Compile error, Message2 has already been used 

另类的行为(在调试的时候code):

Alternative behaviour (when Debugging code):

addMessage(1, "Message1") //OK 
addMessage(2, "Message2") //OK 
. 
. 
. 
addMessage(N, "MessageN") //OK 
addMessage(2, "Message2") //Assertion failed, because Message2 has already been used 

这样做会的#define 和#undef 指令的智能使用的preferred方式。在一般的preprocessor应以一个巧妙的方法(我不知道这是可能的),也许它可以通过宏的适当组合可以实现使用?任何C preprocessor黑客,可以帮助我解决这个问题?

The preferred way of doing it would be smart usage of #define and #undef directives. In general the preprocessor should be used in a smart way (I am not sure if this is possible) maybe it can be achieved by appropriate combinations of macros? Any C preprocessor hacker that could help me solve this problem?

//编辑:我需要这些信息是唯一的全球性,不仅是code块内(如同if语句功能)。

// I need those messages to be unique globally, not only inside one code block (like function of if-statement).

// EDIT2:这个问题的最好描述是,我有100个不同的源文件,我想检查了preprocessor(或者不是在开始分析与脚本源文件等其他可能的机制的每一次编辑,这将是非常耗时且会增加另一级到一个足够复杂项目)如果一个字符串(或一个preprocessor定义中),使用一个以上的时间。我仍然不知道如何做到这一点(我知道这可能不是在所有可行,但我希望它实际上是)。

// The best description of the problem would be that I have 100 different source files and I would like to check with a preprocessor (or possibly other mechanism other than parsing source files with a script at a start of the compilation every-time, which would be very time-consuming and would add another stage to an enough complicated project) if a string (or a preprocessor definition) was used more than one time. I still have no idea how to do it (I know it may not be possible at all but I hope it actually is).

推荐答案

这会给出错误的重复的字符串:

This will give an error on duplicate strings:

constexpr bool isequal(char const *one, char const *two) {
  return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1))
    : (!*one && !*two);
}

constexpr bool isunique(const char *test, const char* const* list)
{
    return *list == 0 || !isequal(test, *list) && isunique(test, list + 1);
}

constexpr int no_duplicates(const char* const* list, int idx)
{
    return *list == 0 ? -1 : (isunique(*list, list + 1) ? no_duplicates(list + 1, idx + 1) : idx);
}

template <int V1, int V2> struct assert_equality
{
    static const char not_equal_warning = V1 + V2 + 1000;
};

template <int V> struct assert_equality<V, V>
{
    static const bool not_equal_warning = 0;
};

constexpr const char* l[] = {"aa", "bb", "aa", 0};
static_assert(assert_equality<no_duplicates(l, 0), -1>::not_equal_warning == 0, "duplicates found");

这是G ++输出:

g++ -std=c++11 unique.cpp 
unique.cpp: In instantiation of ‘const char assert_equality<0, -1>::not_equal_warning’:
unique.cpp:29:57:   required from here
unique.cpp:20:53: warning: overflow in implicit constant conversion [-Woverflow]
unique.cpp:29:1: error: static assertion failed: duplicates found

第一个模板参数(在这种情况下,0),以assert_equality告诉你一个重复的字符串的拳头地位。

The first template parameter (in this case 0) to 'assert_equality' tells you the fist position of a duplicate string.

这篇关于实现一个字符串的编译时间检查机制的独特性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆