9

Code analysis:

ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_HISTORY_TYPE,
  &CAssignHistoryDlg::OnTcnSelchangeTabHistoryType)

Warning C26454:

Arithmetic overflow: '-' operation produces a negative unsigned result at compile time (io.5).

The definition of TCN_SELCHANGE is:

#define TCN_FIRST (0U-550U)
#define TCN_SELCHANGE           (TCN_FIRST - 1)

I can't see what else I can do!

Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • 2
    Infact I get LOTS of these errors. Never used used to. So things have changed in VC. – Andrew Truckle Jul 02 '18 at 15:30
  • 4
    They should have used `#define TCN_FIRST 0xFFFFFDDA` instead of trying to be fancy. You can redefine the constants (not always a good idea) or use `#pragma warning push/pop` to hide the warning. – Barmak Shemirani Jul 02 '18 at 16:44
  • 1
    FYI: https://developercommunity.visualstudio.com/content/problem/285656/warning-c26454-arithmetic-overflow-operation-produ.html – Andrew Truckle Jul 02 '18 at 18:13
  • 3
    You should mention in your submission that this is a "Code Analysis warning" not a compiler warning. – Barmak Shemirani Jul 02 '18 at 19:22
  • 3
    The irony here is that this was probably a result of someone trying to make those constants compile quietly at warning level 4. If `TCN_FIRST` had been defined as `-550U`, then you'd get a compile time warning (because it's suspicious to apply unary minus to an unsigned value). – Adrian McCarthy Jul 02 '18 at 21:07

3 Answers3

8
//windows header file:
#define TCN_FIRST (0U-550U)
#define TCN_SELCHANGE           (TCN_FIRST - 1)

//user file:
...
unsigned int i = TCN_SELCHANGE;

Above code is valid in C++, it should compile without any warning. There is no overflow, that's just meant to be -550U It would be more clear if they wrote it as #define TCN_FIRST 0xFFFFFDDA or 0xFFFFFFFFU-549U

Code Analysis seems to uses a different method and sees an overflow.

Possible solution:

Disable the warning in code:

#pragma warning( push )
#pragma warning( disable : 26454 )

BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
    ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTabHistoryType)
END_MESSAGE_MAP()

#pragma warning( pop )

Or, disable the warning in Code Analysis rule
Use the code analysis rule set editor

enter image description here

Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • I have no Configure menu item. – Andrew Truckle Jul 02 '18 at 19:54
  • 1
    This helped: https://learn.microsoft.com/en-gb/visualstudio/code-quality/how-to-create-a-custom-rule-set. I had to right-click the project and go into properties. Get to it that way. – Andrew Truckle Jul 02 '18 at 20:01
  • It works. In my case the other ones that are still showing that never used to are: C264XX 34, 39, 51 and 95. – Andrew Truckle Jul 02 '18 at 20:09
  • It gets a bit messy either way. It would be nice if Microsoft can find a fix for it, rather than disabling the warning altogether. – Barmak Shemirani Jul 02 '18 at 20:16
  • 1
    I agree. They are rasing things that shouldn't be raised. Particularly when it is their code. Like my other question where a method calls the base then the base method has not been hidden because it has specifically been called. – Andrew Truckle Jul 02 '18 at 20:23
2

You are trying to subtract a larger unsigned value from a smaller unsigned value and it's causing the result to wrap past zero. In your case, I assume TCN_FIRST is defined as 0 so setting TCN_SELCHANGE to one will fix the problem.

You should also be using constexpr or const instead of defines anyway.

According to MSDN:

Arithmetic overflow checks in C++ Core Check

C26451 RESULT_OF_ARITHMETIC_OPERATION_CAST_TO_LARGER_SIZE :[operator] operation wraps past 0 and produces a large unsigned number at compile time. This warning indicates that the subtraction operation produces a negative result which was evaluated in an unsigned context. This causes the result to wrap past 0 and produce a really large unsigned number, which can result in unintended overflows.

1 // Example source:
2 unsigned int negativeunsigned() {
3    const unsigned int x = 1u - 2u; // C26454 reported here
4    return x;
5 }

1 // Corrected source:
2 unsigned int negativeunsigned() {
3     const unsigned int x = 4294967295; // OK
4     return x;
5 }

In the corrected source, a positive value was assigned to the unsigned result.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
Casey
  • 10,297
  • 11
  • 59
  • 88
0

I have just started using MFC dialogs and have the same problem as above when using TVN_SELCHANGED (it generates 0-58U), which comes from:

#define TVN_SELCHANGEDW (TVN_FIRST-51) found in commctrl.h from Microsoft.

However, it does not cause the program to fail compilation. I think that preventing that error message, may cause other headaches if an actual math operation is really a problem. I suppose redefining the constant is a (slightly) better way to go (provided a good comment is provided for future reference), unless you are using lots of these constants.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
DocDJ
  • 31
  • 5
  • I have no intention of changing any MFC defined constants. It is something I have to live with. It is up to Microsoft as to whether the update the SDK to have more appropriate values. But we are talking 5 years now, so I doubt it. – Andrew Truckle Jan 09 '23 at 15:55
  • I also mention the same definition as a comment to my question. – Andrew Truckle Jan 09 '23 at 15:56