Is there a way to disable implicit casts from UInt32 to char?

旧巷老猫 提交于 2019-12-08 20:43:05

问题


I am working on code that takes as input a ton of ascii text defined by specific protocol. The original author interpreted "string(1)" datatypes in the original protocol as chars in the code.

There have been a lot subtle bugs in corner cases where you have code such as:

char theChar = whatever();
if(theChar == 7) {...} 

where was was really meant was:

if(theChar == '7') {...}

In order to attempt to catch all of these at once, is there a way to disable the implicit casting to 'char'? If not, what is the best way to go about tracking all of these down?


回答1:


You should be able to write a trivial replacement class for char (which holds a char as its data, and provides a few cast operators to allow it to be used as if it were a char) that doesn't allow implicit casts to/from ints, and then do a search and replace of 'char' with the 'mychar'. This will throw up compiler errors that you can fix, and then if you wish you can revert the code to using char again, or stick with your class.

This is a good example of a place where temporary use of macros is so useful in c++...




回答2:


My suggestion to find existing errors such as the one described is to use Visual Studio to perform a search across the entire solution (Ctrl+Shift+F) using regular expressions.

  • Press Ctrl+Shift+F
  • Select "Use: regular expressions" under "Find options"
  • Enter the following regular expression into the "Find what" field: [^0-9a-zA-Z_][0-9]+[^0-9]

I think that this will list all occurrences of a literal number in the source code. You can then glance through the search results to see if any of them require further investigation.

You can further narrow down the search results by focusing on a specific type of problem. For instance, to find the code in the provided example, you could adjust the expression to the following: ==( |\t|\r|\n)*[0-9]+[^0-9]


Original Answer

I can't offer any good suggestion to avoid this problem other than to try to avoid "magic" values in code.

Assuming that this code is being used in some kind of menu selection logic, I feel like perhaps the code should be something like this:

static class MenuSelection
{
    public const char Open = '1';
    public const char Edit = '2';
    public const char Save = '3';
    // ...
    public const char Close = '7';
}

And then MenuSelection should be used in the if statement as shown below:

char theChar = whatever();
if(theChar == MenuSelection.Close) {...} 

This doesn't really address the problem of the implicit conversion from UInt32 to char, but hopefully the person writing the code for the constants in the MenuSelection class will be less likely to forget the quotes.

EDIT: Oh, after giving it a try, it seems like this does kind of address the implicit conversion issue, because public const char Close = 7; produces a compile error.

Unfortunately, it doesn't help your immediate problem: a lot of existing code containing these kinds of bugs.




回答3:


As a "fix once" solution I think James Michael Hare's FxCop solution is the easiest.

To keep it from being a problem in the future refactoring to use a custom datatype instead of char so you can define the exact operations you want available may be a good idea.




回答4:


No, the behavior allowing the expression theChar == 7 is part of the C# specification, and can't be changed.

Note that the actual implicit conversion here is from char to int, not from int to char.

Here's how it works:

  • The literal 7 has type int.
  • The variable theChar has type char.
  • To apply the == operator to the two expressions, the compiler must choose an == operator.
    • There is no == operator that takes a char as the first argument and an int as the second.
    • There is no implicit conversion from int to char (because such a conversion can lose information).
    • There is an implicit conversion from char to int.
    • The compiler converts the char expression to int, and uses the == operator that takes two ints.


来源:https://stackoverflow.com/questions/8762949/is-there-a-way-to-disable-implicit-casts-from-uint32-to-char

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!