简体   繁体   English

在 C++ 的 switch case 中将指针强制转换为 unsigned int

[英]cast pointer to unsigned int in a switch case in C++

I have a C header file that has a list of definitions like below我有一个C header 文件,其中包含如下定义列表

#define TAG_A   ((A*)0x123456)
#define TAG_B   ((B*)0x456789)

I include that file in a cpp file.我将该文件包含在cpp文件中。
I want to cast those definition in a switch case like below我想将这些定义转换为如下所示的switch case

unsigned int get_tag_address(unsigned int i)
{
    switch(i)
    {
        case reinterpret_cast<unsigned int>(TAG_A):
        return 1;
        case reinterpret_cast<unsigned int>(TAG_B):
        return 2;
    }
    return 3;
}

I still get compiler error that I can't cast a pointer to an unsigned intigeter.我仍然得到编译器错误,我无法将指针转换为无符号整数。

What do I do wrong?我做错了什么?

The definitions look at hardware addresses of an embedded system.这些定义着眼于嵌入式系统的硬件地址。 I want to return an unsigned integer based on what hardware component is used (ie passed into the function argument).我想根据使用的硬件组件返回一个未签名的 integer(即传递到 function 参数)。 This is how I ended up in that situation.这就是我最终陷入那种境地的原因。

PS: The header file containing the defitions must not change . PS:包含定义的 header 文件不得更改

It is impossible to use TAG_A and TAG_B in a case of a switch , except by using preprocessor tricks like stringifying the macro replacement itself in a macro and then parsing the value form the resulting string, which will however make the construct dependent on the exact form of the TAG_X macros and I feel is not really worth it when you don't have a strict requirement to obtain compile-time constant values representing the pointers.switchcase使用TAG_ATAG_B是不可能的,除非使用预处理器技巧,例如在宏中将宏替换本身字符串化,然后从结果字符串中解析值,但是这将使构造依赖于确切的形式TAG_X宏,当您没有严格要求获取表示指针的编译时常量值时,我觉得这并不值得。

The results of the expressions produced by the TAG_A and TAG_B replacement can not be used in a case operand because the operand must be a constant expression, but casting an integer to a pointer as done with (A*) and (B*) disqualifies an expression from being a constant expression.TAG_ATAG_B替换产生的表达式的结果不能用于case操作数,因为操作数必须是常量表达式,但是将 integer 转换为使用(A*)(B*)完成的指针会取消资格表达式从一个常量表达式。

So, you will need to use if / else if instead:因此,您将需要使用if / else if来代替:

unsigned int get_tag_address(unsigned int i)
{
    if(i == reinterpret_cast<unsigned int>(TAG_A)) {
        return 1;
    } else if(i == reinterpret_cast<unsigned int>(TAG_B)) {
        return 2;
    } else {
        return 3;
    }
}

Also, consider using std::uintptr_t instead of unsigned int for i and in the reinterpret_cast s, since it is not guaranteed that unsigned int is large enough to hold the pointer values.此外,请考虑在ireinterpret_cast s 中使用std::uintptr_t而不是unsigned int ,因为不能保证unsigned int足够大以容纳指针值。 However, compilation of the reinterpret_cast should fail if unsigned int is in fact too small.但是,如果unsigned int实际上太小,则reinterpret_cast的编译应该会失败。 (It is possible that std::uintptr_t in <cstdint> does not exist, in which case you are either using pre-C++11 or, if not that, it would be a hint that the architecture does not allow for representing pointers as integer values. It is not guaranteed that this is possible, but you would need to be working some pretty exotic architecture for it to not be possible.) <cstdint>中的std::uintptr_t可能不存在,在这种情况下,您使用的是 C++11 之前的版本,或者,如果不是,则暗示该体系结构不允许表示指针作为 integer 值。不能保证这是可能的,但您需要使用一些非常奇特的架构才能使其不可能。)

And if you can, simply pass, store and compare pointers (maybe as void* ) instead of integer values representing the pointers.如果可以,只需传递、存储和比较指针(可能为void* )而不是代表指针的 integer 值。 That is safer for multiple reasons and always guaranteed to work.出于多种原因,这更安全,并且始终可以保证工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM