简体   繁体   English

是否有可能在编译期间错误检查case语句选项?

[英]Is it possible to error check case statement options during compile time?

How can I rewrite this code in such a way that user is always shown the correct state(CA,AL etc.) string whenever he passes a valid direction. 如何以这样的方式重写此代码:只要用户通过有效方向,就会始终显示正确的状态(CA,AL等)字符串。

ie How do I make sure there is a valid case statement for each of those enum_types in the directions enum during compile time than in runtime? 即如何确保编译时枚举方向中的每个enum_types都有一个有效的case语句,而不是运行时?

For. 对于。 Eg. 例如。 I have intentionally commented out the case statement for east. 我故意评论了东方的案例陈述。 Is there a way to catch this at compile time. 有没有办法在编译时捕获它。

My gut feel is (NO) that this is why the language provides a default case and hence this may not be possible. 我的直觉是(否)这就是语言提供默认情况的原因,因此这可能是不可能的。 But I'll leave this to the experts. 但我会把它留给专家。

#include <iostream>
#include <string>

using namespace::std;

typedef enum 
{
    min_dir = -1,
    north,
    south,
    east,
    west,
}directions;

directions get_direction( string user_choice)
{
    if(user_choice == "north")
    {
        return north;
    }
    else if (user_choice == "south")
    {
        return south;   
    }
    else if (user_choice == "east")
    {
        return east;    
    }
    else if (user_choice == "west")
    {
        return west;    
    }
    else 
    {
        return min_dir;
    }
}

int main()
{
    string user_direction;
    cout << "Enter direction\n";
    cin >> user_direction;

    directions my_dir = get_direction(user_direction);
    cout << " Print direction's description\n";

    if( my_dir == min_dir)
    {
        // User passed junk
        return -1;
    }

    switch(my_dir)
    {
    case north:
        cout << "North - New york\n";break;
    case south:
        cout << "South - Alabama\n";break;
//  case east:
//      cout << "East - North Carolina\n";break;
    case west:
        cout << "West - California\n";break;
    default:
        cout << "Should Ideally never get here\n";break;
    }
    system("pause");
    return 0;
}

Edit: This is just an example to illustrate the point. 编辑:这只是一个例子来说明这一点。 This for code at work. 这是代码在工作。 They have compile this both in Windows(MSVC) and linux (gcc). 他们在Windows(MSVC)和linux(gcc)中都编译了这个。 Would this only be a warning? 这只是一个警告吗? I'll need a stricter enforcement. 我需要更严格的执法。

Can I write some code that will error out during a make process if an enum doesn't have a case statement? 如果枚举没有case语句,我可以编写一些在make过程中会出错的代码吗?

In GCC (g++) and Clang, there is -Wswitch-enum , which will warn you if you do not have a case for a possible value for the enum type you're switch ing over (even if you have a default case). 在GCC(g ++)和Clang中,有-Wswitch-enum ,如果你没有关于你要switchenum类型的可能值的case (即使你有一个default情况),它会发出警告。

In MSVC, there is the comparable C4062 which comes from warning level 3, but it will not warn you if you have a default statement. 在MSVC中,可比较的C4062来自警告级别3,但如果您有default语句,它不会警告您。 If you want warnings in that case, you need to enable the level 4 warning C4061 , which produces a warning when an enumerated value is missing, even if a default case is provided. 如果在这种情况下需要警告,则需要启用级别4警告C4061 ,即使提供了默认情况,也会在缺少枚举值时生成警告。

As far as making it an error goes: all compilers have a "treat warnings as errors" option. 至于使其成为错误:所有编译器都有“将警告视为错误”选项。 In GCC and Clang, it's -Werror ; 在GCC和Clang中,它是 - -Werror ; in MSVC, it's /WX . 在MSVC中,它是/WX

If you use a an array of functors sized to your enum and initialized when declared then you can do a static_assert on the size of the array vs the enum count to verify all members are present. 如果你使用一个对你的枚举大小的子函数数组,并在声明时初始化,那么你可以对数组的大小和枚举数进行static_assert来验证所有成员是否存在。 By using functors in the array rather than function pointers, you are also sure that you didn't supply an nullptr as values since each functor will be constructed. 通过在数组中使用仿函数而不是函数指针,您还确定不会将nullptr作为值提供,因为将构造每个仿函数。

typedef enum 
{
    min_dir = -1,
    north = 0,
    south,
    count_dir
}directions;

class GoDir
{
public:
    virtual void operator()() {}
};

class GoNorth : public GoDir
{
public:
    virtual void operator()() {}
};

class GoSouth : public GoDir
{
public:
    virtual void operator()() {}
};

static GoDir actions[count_dir] = {GoNorth(), GoSouth()};
static_assert(sizeof(actions)/sizeof(actions[0]) == count_dir, "Error");

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

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